Database (Oracle 11g) query optimization for joins - sql

So I am trying to optimize a bunch of queries which are taking a lot of time. What I am trying to figure out is how to create an index on columns from different tables.
Here is a simple version of my problem.
What I did
After Googling I looked into bitmap index but I am not sure if this is the right way to solve the issue
Issue
There is a many to many relationship b/w Student(sid,...) and Report(rid, year, isdeleted)
StudentReport(id, sid, rid) is the join table
Query
Select *
from Report
inner join StudentReport on Report.rid = StudentReport.rid
where Report.isdeleted = 0 and StudentReport.sid = x and Report.year = y
What is the best way to create an index?

Please try this:
with TMP_REP AS (
Select * from Report where Report.isdeleted = 0 AND Report.year = y
)
,TMP_ST_REP AS(
Select *
from StudentReport where StudentReport.sid = x
)
SELECT * FROM TMP_REP R, TMP_ST_REP S WHERE S.rid = R.rid

Related

Determining what index to create given a query?

Given a SQL query:
SELECT *
FROM Database..Pizza pizza
JOIN Database..Toppings toppings ON pizza.ToppingId = toppings.Id
WHERE toppings.Name LIKE '%Mushroom%' AND
toppings.GlutenFree = 0 AND
toppings.ExtraFee = 1.25 AND
pizza.Location = 'Minneapolis, MN'
How do you determine what index to write to improve the performance of the query? (Assuming every value to the right of the equal is calculated at runtime)
Is there a built in command SQL command to suggest the proper index?
To me, it gets confusing when there's multiple JOINS that use fields from both tables.
For this query:
SELECT *
FROM Database..Pizza p JOIN
Database..Toppings t
ON p.ToppingId = t.Id
WHERE t.Name LIKE '%Mushroom%' AND
t.GlutenFree = 0 AND
t.ExtraFee = 1.25 AND
p.Location = 'Minneapolis, MN';
You basically have two options for indexes:
Pizza(location, ToppingId) and Toppings(id)
or:
Toppings(GlutenFree, ExtraFee, Name, id) and Pizza(ToppingId, location)
Which works better depends on how selective the different conditions are in the WHERE clause.

Faster way compare changes between SQL sub-queries?

I need to check for the change in the color of cats between two dates.
I have the query below:
WITH
cats_prior AS (SELECT IDTAG,Color FROM CATS WHERE APPOINTMENT = '06/30/2019'),
cats_now AS (SELECT IDTAG,Color FROM CATS WHERE APPOINTMENT = '08/31/2019')
SELECT cats_prior.IDTAG, cats_prior.Color,cats_now.Color
FROM cats_prior
JOIN cats_now on cats_prior.IDTAG = cats_now.IDTAG
WHERE cats_prior.Color != cats_now.Color
It works but it takes 11 minutes and there are around 15 million cats in that table.
Is there another way to do this? or a way to make this faster?
This is SQL Server.
I would try aggregation with a HAVING clause:
SELECT IDTAG
FROM CATS
WHERE APPOINTMENT IN ('2019-08-31', '2019-06-30')
GROUP BY IDTAG
HAVING MIN(COLOR) <> MAX(COLOR);
An index on CATS(APPOINTMENT, IDTAG, COLOR) would help. This index might also speed up your version of the query.
Just another way to try the same thing:
select distinct cp.IDTAG
from CATS cp
inner join CATS cn
on cp.IDTAG = cn.IDTAG
and cp.color <> cn.color
where cp.APPOINTMENT = '06/30/2019'
and cn.APPOINTMENT = '08/31/2019'
You can check performance against your data.

How Optimize this complex sql query?

I have the following SQL Query running in a msaccess database query, that takes several seconds,4 or 5 seconds in a good machines. but in the client machine takes many more...I have to optimize this query.
I try making index in some tables like table Lins and MKT .. And seems to get a little better,
The problem is that I have 8 querys like this running one after the other.. and its gettin really slow with more than 400.000 records
SELECT LINs.LIN,
Sum(VentasDet.Cantidad) AS SumaDeCantidad
FROM ((
(SELECT *
FROM ventas
WHERE (CBTE='COT'
OR CBTE='FCA'
OR CBTE='FCB'
OR CBTE='PR'
OR CBTE='RTO'
OR CBTE='TK')
AND (Suc=0
OR Suc=1
OR Suc=2
OR Suc=4
OR Suc=5)
AND (Caja=0
OR Caja=1
OR Caja=2)
AND (PRDO='12-2017'
OR PRDO='11-2017'
OR PRDO='10-2017'
OR PRDO='09-2017')
AND (MKT=1
OR MKT=2
OR MKT=3
OR MKT=4
OR MKT=5) ) AS Ventas
INNER JOIN
(SELECT *
FROM VentasDet
WHERE LIN<>'0-'
AND LIN<>'1AS'
AND LIN<>'1VF'
AND LIN<>'NEW'
AND LIN<>'OSE'
AND LIN<>'OLJ'
AND LIN<>'OS-O' ) AS VentasDet ON (Ventas.Numero = VentasDet.Numero)
AND (Ventas.Suc = VentasDet.Suc)
AND (Ventas.CBTE = VentasDet.CBTE))
INNER JOIN
(SELECT Codigo,
MaMi
FROM Clis
WHERE MaMi=0
OR MaMi=1
OR MaMi=2 ) AS Clis ON Ventas.Cli = Clis.Codigo)
INNER JOIN LINs ON VentasDet.LIN = LINs.Codigo
GROUP BY VentasDet.LIN,
LINs.LIN
ORDER BY Sum(VentasDet.Cantidad) DESC
Can you try below to see if it make any difference?
1. make a middle table to join CBTE;
2. make a middle table VentasDet;
create table CBTE (CBTE varchar(3));
insert into CBTE values('COT', 'FCA', 'FCB', 'PR','RTO', 'TK');
create table LIN (LIN varchar(4));
insert into LIN values('0-','1AS','1VF','NEW','OSE','OLJ','OS-O');
( SELECT *
FROM VentasDet V
left join LIN L on v.Lin=L.Lin where L.Lin is null) AS VentasDet

SQL - How to eliminate duplicates from the below query in POSTGRES

I have been working on the below query. Basically there are two tables. Realtime_Input and Realtime_Output. When I join the two tables and take the necessary columns, I made this a view and when i query against the view I get duplicates.
What am I doing wrong? When I tested using distinct keyword, I get 60 unique rows but intermittently i get duplicates. My db is on cloud foundry cloud (postgres). Is is because of that? Please help !
select i2.key_ts_long,
case
when i2.revenue_activepower = 'NA'
then (-1 * CAST(io.min5_forecast as real))
else (CAST(i2.revenue_activepower AS real) - CAST(io.min5_forecast as real))
end as diff
from realtime_analytic_input i2,
(select i.farm_id,
i.key_ts_long,
o.min5_forecast,
o.min5_timestamp_seconds
from realtime_analytic_input i,
realtime_analytic_output o
where i.farm_id = o.farm_id
and i.key_ts_long = o.key_ts_long
and o.farm_id = 'MW1'
) io
where i2.key_ts_long = CAST(io.min5_timestamp_seconds AS bigint)
and i2.farm_id = io.farm_id
and i2.farm_id = 'MW1'
and io.key_ts_long between 1464738953169 and 1466457841
order by io.key_ts_long desc

SQL query for filtering data

I`m working on some sql queries to get some data out of a table; I have made 2 queries for the
same data but both give another result. The 2 queries are:
SELECT Samples.Sample,
data_overview.Sample_Name,
data_overview.Sample_Group,
data_overview.NorTum,
data_overview.Sample_Plate,
data_overview.Sentrix_ID,
data_overview.Sentrix_Position,
data_overview.HybNR,
data_overview.Pool_ID
FROM tissue INNER JOIN (
( patient INNER JOIN data_overview
ON patient.Sample = data_overview.Sample)
INNER JOIN Samples ON
(data_overview.Sample_id = Samples.Sample_id) AND
(patient.Sample = Samples.Sample)
) ON
(tissue.Sample_Name = data_overview.Sample_Name) AND
(tissue.Sample_Name = patient.Sample_Name)
WHERE data_overview.Sentrix_ID= 1416198
OR data_overview.Pool_ID='GS0005701-OPA'
OR data_overview.Pool_ID='GS0005702-OPA'
OR data_overview.Pool_ID='GS0005703-OPA'
OR data_overview.Pool_ID='GS0005704-OPA'
OR data_overview.Sentrix_ID= 1280307
ORDER BY Samples.Sample;")
And the other is
SELECT Samples.Sample,
data_overview.Sample_Name,
data_overview.Sample_Group,
data_overview.NorTum,
data_overview.Sample_Plate,
data_overview.Sentrix_ID,
data_overview.Sentrix_Position,
data_overview.HybNR,
data_overview.Pool_ID
FROM tissue INNER JOIN
(
(patient INNER JOIN data_overview
ON patient.Sample = data_overview.Sample)
INNER JOIN Samples ON
(data_overview.Sample_id = Samples.Sample_id)
AND (patient.Sample = Samples.Sample)) ON
(tissue.Sample_Name = data_overview.Sample_Name)
AND (tissue.Sample_Name = patient.Sample_Name)
WHERE ((
(data_overview.Sentrix_ID)=1280307)
AND (
(data_overview.Pool_ID)="GS0005701-OPA"
OR (data_overview.Pool_ID)="GS0005702-OPA"
OR (data_overview.Pool_ID)="GS0005703-OPA"
OR (data_overview.Pool_ID)="GS0005704-OPA"))
OR (((data_overview.Sentrix_ID)=1416198))
ORDER BY data_overview.Sample;
The one in the top is working quite well but it still won't filter the sentrix_ID.
The second 1 is created with Access but when I try to run this Query in R it gave
a unexpected symbol error. So if anyone knows how to create a query that filter POOL_ID and Sentrix_id with the given parameters thanks in advance
Is it a case of making the where clause something like this:
WHERE Sentrix_ID = 1280307 AND (Pool_ID = 'VAL1' OR Pool_ID = 'VAL2' OR Pool_ID = 'VAL3')
i.e. making sure you have brackets around the "OR" components?
Maybe you meant:
...
WHERE data_overview.Sentrix_ID IN (1280307,1416198 )
AND data_overview.Pool_ID IN ("GS0005701-OPA", "GS0005702-OPA", "GS0005703-OPA" ,"GS0005704-OPA")
;