开发者

Index on UNION query?

i've got this union query:

(SELECT INSTALLER, INSTALLTIME, 开发者_高级运维RESULT, JOBNUMBER, HONAME, ADDRESS, CITY, STATE, ZIP, NOTES, SMNOTES, '' as priority, PAFS, upsell, TERM, MMRUPGRADE, WARRANTY, EFT FROM ACCOUNTS 
WHERE INSTALLDATE = '$date' && FUNDINGSTATUS !='DEAD') 
UNION 
(SELECT technician, servicetime, result, ID, Customername, address, city, state, zip, notes, board, priority, '', '', '', '', '', '' FROM service 
WHERE serviceday = '$date') 
ORDER BY INSTALLER, priority

i'm curious if putting an index on the date field will help speed up both queries? or will the fact that i use FUNDINGSTATUS in the first where clause will make that query not utilize the index?


Most likely it will help, but the only way to be sure is to break open the profiler, and have a look. Starting with version 5.0.37, MySQL has a built-in profiler.

Enable it with

set profiling=1;

To lookup the query_id

show profiles;

And to see the execution plan:

show profile for query x;


Answering your very question:

I'm curious if putting an index on the date field will help speed up both queries?

If the condition on installdate and serviceday is selective (that is few rows satisfy it), then yes, it will help.

Date fields usually tend to be selective.

or will the fact that i use FUNDINGSTATUS in the first where clause will make that query not utilize the index?

Yes, the index will still be used.

The engine will use the index to select only the records with installdate = $date and the will additionally filter on the value of fundingstatus.

For best results, create the following indexes:

ACCOUNTS  (installdate, fundingstatus)
service (serviceday)

If DEAD is a frequent value for fundingstatus, it may be better to rewrite this query like this:

SELECT  INSTALLER, INSTALLTIME, RESULT, JOBNUMBER, HONAME, ADDRESS, CITY, STATE, ZIP, NOTES, SMNOTES, '' as priority, PAFS, upsell, TERM, MMRUPGRADE, WARRANTY, EFT
FROM    ACCOUNTS 
WHERE   INSTALLDATE = '$date' AND FUNDINGSTATUS < 'DEAD'
UNION ALL
SELECT  INSTALLER, INSTALLTIME, RESULT, JOBNUMBER, HONAME, ADDRESS, CITY, STATE, ZIP, NOTES, SMNOTES, '' as priority, PAFS, upsell, TERM, MMRUPGRADE, WARRANTY, EFT
FROM    ACCOUNTS 
WHERE   INSTALLDATE = '$date' AND FUNDINGSTATUS > 'DEAD'
UNION
SELECT  technician, servicetime, result, ID, Customername, address, city, state, zip, notes, board, priority, '', '', '', '', '', ''
FROM    service 
WHERE   serviceday = '$date'
ORDER BY
        INSTALLER, priority

so that the range access on both fields (installdate, fundingstatus) can be used.


Having the index on any field in the where clause can always improve the performance, whether by a lot or a little.

To answer your question of whether the index on "date" will be used despite first query having "FUNDINGSTATUS" in the where clause has 2 answers:

  • If there are NO OTHER indexes on the table, then the date index will most definitely be used. That is because finding records with the specific date by index is a lot less work for the DB than searching the entire table, even if it does need to check the FUNDINGSTATUS after finding said records.

  • If there ARE other indexes on the same table, then the answer is "it depends".

    It mostly depends on what % of the data will be data that's notd ead vs. % of the data for a given date.

    The optimizer usually tries to choose the index that will right away pick the smallest # of columns - e.g. if your table has data for 100 days and 1/2 of them is dead rows, then the date index will be chosen because it gives you 1% of the data without scanning the table vs. 50% of the data.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜