my sub query is taking too much time - mysql

I have simple query but it is taking too much time for execution.
query:
SELECT a.primarykey,
a.SID,
a.VID,
a.topic,
a.dstart,
a.dstop,
a.vresult,
a.dstart1,
a.dstart2,
( SELECT MIN(d.vresult)
FROM _temp._pb_1_1_4_1 d
WHERE d.dstart1 > a.dstart1
) as _DOP0
FROM _temp._pb_1_1_4_1 a
column dstart1 is indexed.
dstart1 is Date type column.
Please help me to optimized above query.
if I remove d.dstart1 > a.dstart1 from the WHERE clause then query run very fast.
whenI explain the query it gives "Range checked for each record (index map: 0x1)"
I want to achieve minimum value of vresult for each row.
For each row , First filter all the records which has greater value of dstart1 for the same table and then find min(vresult) for that row.

Without knowing anything about what you're trying to do... this query should return the same results and has been removed the unnecessary calculations:
select a.primarykey, a.SID, a.VID, a.topic, a.dstart, a.dstop,
a.vresult, a.dstart1, a.dstart2, (
select MIN(d.vresult)
from _temp._pb_1_1_4_1 d
where d.dstart1 > a.dstart1) _DOP0
from _temp._pb_1_1_4_1 a
Anyway, it would help to understand what you're trying to do with that query.

Related

Filtering empty rows from SQL query

I am trying to form an SQL query to retrieve some records, however the issue I am having is that my query retrieving empty rows.
The query below retrieves the following rows, however I need the last few rows not to appear. I tried adding AND vanDeduction != '' to the end of this query, but this makes it miss important data.
SELECT rnumber,date,grossInvoice,sTaxFee1Charged,vanDeduction
FROM ledger
where rnumber = 'R-022074'
Thank you for your help!
You seem to want:
SELECT rnumber, date, grossInvoice, sTaxFee1Charged, vanDeduction
FROM ledger
WHERE rnumber = 'R-022074' AND
(grossInvoice > 0 or sTaxFee1Charged > 0 or driverPayment > 0);

mysql where subquery with not in works, but subquery with in does not work

belHere is a MySql query that works just fine:
select PersonId
, PersonState
, PersonZip5
from perslabel
where PersonCountry = 'USA'
and concat(PersonState,PersonZip5) is not null
and concat(PersonState,PersonZip5) Not In
(select concat(Z3StateCode,Zip3Code) as statezip from Zip3)
There are five records in the table perslabel, two of them should be selected by this query, and that is exactly what happens.
Here is a MySql query that does not work:
select PersonId, PersonState, PersonZip5 from perslabel
where concat(PersonState,PersonZip5) IN
(select concat(Z3StateCode,Zip3Code) as statezip from Zip3)
This query should return 3 records, but it returns none.
I can't think why changing "not in" to "in" should matter. None of the concat combos are null, and adding that line to the second query makes no difference -- I still get 0 records.
I'm baffled about why the second query does not work. Can anyone enlighten me? Or tell me how to fix it?

Crosstab Query from a Query with a Subquery

Can anyone help me with a problem I am having with a CrossTab Query to compare current prices from our suppliers?
The select Query that it works from has a sub query that selects on only the most resent prices for our price comparison and this works perfectly for the data we need, see below:
qryPriceComp:
SELECT tblPriceComp.SupplyerID, tblPriceComp.ProductID,
tblPriceComp.Effdt, tblPriceComp.CostPrice,
tblProduct.Product, tblSupplier.Supplier
FROM tblSupplier INNER JOIN
(tblProduct INNER JOIN tblPriceComp ON tblProduct.ProductID = tblPriceComp.ProductID)
ON tblSupplier.SupplierID = tblPriceComp.SupplyerID
WHERE (((tblPriceComp.Effdt) In
(SELECT MAX(B.EffDt) AS MaxOfDt FROM tblPriceComp AS B
WHERE tblPriceComp.ProductID=B.ProductID
AND tblPriceComp.SupplyerID=B.SupplyerID
AND B.EffDt <= Date()+1)));
This is then used for the crosstab query
qryPriceComp_Crosstab:
TRANSFORM Sum(qryPriceComp.CostPrice) AS SumOfCostPrice
SELECT qryPriceComp.Product
FROM qryPriceComp
GROUP BY qryPriceComp.Product
ORDER BY qryPriceComp.Product, qryPriceComp.Supplier
PIVOT qryPriceComp.Supplier;
But when run it gives an error that both tblPriceComp.ProductID and tblSupplier.SupplierID are invalid. I have tried adding them as perimeters but when run this gives a box to enter the ID numbers which is no good as we want to see all productIDs and SupplyerIDs. If anyone can help it would be greatly appreciated!
Not a real solution, but a usable workaround:
Change qryPriceComp to a INSERT INTO tempTable query, and then base the crosstab query on tempTable.
Before each INSERT run, a DELETE * FROM tempTable must be executed.

Why this Query takes such a long time to execute

I have three tables
glSalesJournal
HMISAdd
HMISMain
Now what i am trying to do is add the glSalesJournal amt with HMISAdd amt while grouping up with various Fields and inserting the result into glSalesJournal
The glSalesJournal contains 633173 records
The HMISAdd contains 4193 records
HMISAdd and glSalesJournal contains the same columns which are
loc
glAcct
glSubAcct
batchNbr
contractNbr
amt
I added indexes to the table still the results are the same.
Here is my code:
INSERT INTO hmismain
(loc,
glacct,
subacct,
batchnbr,
contractnbr,
amt)
SELECT glsalesjournal.loc,
glsalesjournal.glacct,
glsalesjournal.glsubacct,
( glsalesjournal.amt + hmisadd.amt ) AS sumAmt,
glsalesjournal.batchnbr,
glsalesjournal.salescontnbr
FROM glsalesjournal
LEFT OUTER JOIN hmisadd
ON ( glsalesjournal.loc = hmisadd.loc
AND glsalesjournal.glacct = hmisadd.glacct
AND glsalesjournal.glsubacct = hmisadd.subacct
AND glsalesjournal.batchnbr = hmisadd.batchnbr
AND glsalesjournal.salescontnbr = hmisadd.contractnbr )
GROUP BY glsalesjournal.loc,
hmisadd.loc,
glsalesjournal.glacct,
hmisadd.glacct,
glsalesjournal.glsubacct,
hmisadd.subacct,
glsalesjournal.batchnbr,
hmisadd.batchnbr,
glsalesjournal.salescontnbr,
hmisadd.contractnbr
The time taken by the script to execute is more than 2 hours. Even when I limit the Records to 100 the time taken is the same.
Can someone please guide me how can I optimize the script.
Thanks
1) It looks like it's a one off query, am I correct here? If not than you are inserting the same data into hmismain table every time.
2) You are grouping on fields from TWO separate tables, so no amount of indexing will ever help you. The ONLY index that will help is an index over a view linking these two tables in the same way.
Further note:
What is the point of
GROUP BY glsalesjournal.loc,
hmisadd.loc,
glsalesjournal.glacct,
hmisadd.glacct,
glsalesjournal.glsubacct,
hmisadd.subacct,
glsalesjournal.batchnbr,
hmisadd.batchnbr,
glsalesjournal.salescontnbr,
hmisadd.contractnbr
You are grouping the data by the same fields twice
glsalesjournal.loc, hmisadd.loc
glsalesjournal.glacct, hmisadd.glacct,
...
Remove the duplicates from GROUP BY and it should run fast
Did you add an index on this fields:
glSalesJournal.loc
glSalesJournal.glAcct
glSalesJournal.glSubAcct
glSalesJournal.batchNbr
glSalesJournal.salesContNbr
HMISAdd.Loc
HMISAdd.GlAcct
HMISAdd.SubAcct
HMISAdd.batchNbr
HMISAdd.contractNbr
If this fields are unindexed, it will perform fulltable scan for each individual record thus causing slow performance.
MySQL Create Index Syntax

How to avoid filesort for that mysql query?

I'm using this kind of queries with different parameters :
EXPLAIN SELECT SQL_NO_CACHE `ilan_genel`.`id` , `ilan_genel`.`durum` , `ilan_genel`.`kategori` , `ilan_genel`.`tip` , `ilan_genel`.`ozellik` , `ilan_genel`.`m2` , `ilan_genel`.`fiyat` , `ilan_genel`.`baslik` , `ilan_genel`.`ilce` , `ilan_genel`.`parabirimi` , `ilan_genel`.`tarih` , `kgsim_mahalleler`.`isim` AS mahalle, `kgsim_ilceler`.`isim` AS ilce, (
SELECT `ilanresimler`.`resimlink`
FROM `ilanresimler`
WHERE `ilanresimler`.`ilanid` = `ilan_genel`.`id`
LIMIT 1
) AS resim
FROM (
`ilan_genel`
)
LEFT JOIN `kgsim_ilceler` ON `kgsim_ilceler`.`id` = `ilan_genel`.`ilce`
LEFT JOIN `kgsim_mahalleler` ON `kgsim_mahalleler`.`id` = `ilan_genel`.`mahalle`
WHERE `ilan_genel`.`ilce` = '703'
AND `ilan_genel`.`durum` = '1'
AND `ilan_genel`.`kategori` = '1'
AND `ilan_genel`.`tip` = '9'
ORDER BY `ilan_genel`.`id` DESC
LIMIT 225 , 15
and this is what i get in explain section:
these are the indexes that i already tried to use:
any help will be deeply appreciated what kind of index will be the best option or should i use another table structure ?
You should first simplify your query to understand your problem better. As it appears your problem is constrained to the ilan_gen1 table, the following query would also show you the same symptoms.:
SELECT * from ilan_gene1 WHERE `ilan_genel`.`ilce` = '703'
AND `ilan_genel`.`durum` = '1'
AND `ilan_genel`.`kategori` = '1'
AND `ilan_genel`.`tip` = '9'
So the first thing to do is check that this is the case. If so, the simpler question is simply why does this query require a file sort on 3661 rows. Now the 'hepsi' index sort order is:
ilce->mahelle->durum->kategori->tip->ozelik
I've written it that way to emphasise that it is first sorted on 'ilce', then 'mahelle', then 'durum', etc. Note that your query does not specify the 'mahelle' value. So the best the index can do is lookup on 'ilce'. Now I don't know the heuristics of your data, but the next logical step in debugging this would be:
SELECT * from ilan_gene1 WHERE `ilan_genel`.`ilce` = '703'`
Does this return 3661 rows?
If so, you should be able to see what is happening. The database is using the hepsi index, to the best of it's ability, getting 3661 rows back then sorting those rows in order to eliminate values according to the other criteria (i.e. 'durum', 'kategori', 'tip').
The key point here is that if data is sorted by A, B, C in that order and B is not specified, then the best logical thing that can be done is: first a look up on A then a filter on the remaining values against C. In this case, that filter is performed via a file sort.
Possible solutions
Supply 'mahelle' (B) in your query.
Add a new index on 'ilan_gene1' that doesn't require 'mahelle', i.e. A->C->D...
Another tip
In case I have misdiagnosed your problem (easy to do when I don't have your system to test against), the important thing here is the approach to solving the problem. In particular, how to break a complicated query into a simpler query that produces the same behaviour, until you get to a very simple SELECT statement that demonstrates the problem. At this point, the answer is usually much clearer.