Mysql 联合查询上的索引?

Mysql 联合查询上的索引?,mysql,indexing,union,Mysql,Indexing,Union,我有一个工会查询: (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'

我有一个工会查询:

(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

我很好奇,在日期字段中添加索引是否有助于加快这两个查询的速度?或者我在第一个where子句中使用FUNDINGSTATUS这一事实会使该查询不使用索引吗?

这很可能会有所帮助,但唯一可以确保的方法是打开探查器,并进行查看。从版本5.0.37开始,MySQL有一个内置的

使用

set profiling=1;
查找查询id的步骤

show profiles;
并查看执行计划:

show profile for query x;

回答你的问题:

我很好奇,在日期字段中添加索引是否有助于加快这两个查询的速度

如果installdate和serviceday上的条件是选择性的,即只有几行满足它,那么是的,这将有所帮助

日期字段通常是选择性的

或者我在第一个where子句中使用FUNDINGSTATUS的事实会使该查询不使用索引吗

是的,索引仍将使用

引擎将使用索引仅选择installdate=$date的记录,并将额外过滤fundingstatus的值

为获得最佳结果,请创建以下索引:

ACCOUNTS  (installdate, fundingstatus)
service (serviceday)
如果DEAD是fundingstatus的一个常见值,那么最好像这样重写此查询:

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

因此,可以使用installdate、fundingstatus两个字段的范围访问。

在where子句中的任何字段上都有索引总是可以提高性能,无论是提高多少

若要回答您的问题,即尽管where子句中的第一个查询有FUNDINGSTATUS,但是否将使用日期索引,有2个答案:

如果表上没有其他索引,那么最肯定使用日期索引。这是因为,对于DB来说,通过索引查找具有特定日期的记录比搜索整个表要少得多,即使它在找到所述记录后确实需要检查FUNDINGSTATUS

如果同一个表上有其他索引,那么答案是这取决于

这主要取决于未读取数据的百分比和给定日期数据的百分比

优化器通常尝试选择将立即选取最小列的索引-例如,如果您的表有100天的数据,其中1/2是死行,那么将选择日期索引,因为它会为您提供1%的数据而不扫描表,而不是50%的数据


虽然这是正确的,但它实际上并没有回答他提出的问题。死亡还不是很常见,但它会很常见。最终也会有大约6-7个其他资助状态。不过,我只是好奇,范围访问有什么帮助,或者更重要的是,它是如何工作的。我最近刚研究了很多mysql,实际上只见过几次这个词。根据经验,范围访问每行的成本更高,是10倍。这意味着,如果您的条件过滤掉90%以上的行,那么范围访问将更好。在什么意义上,您的意思是昂贵?范围访问使用的索引不包含选择列表中列的值。它需要在表中查找它们。此查找所需时间约为在表中查找所需时间的10倍。如果100%的记录满足您的条件,并且您强制执行范围访问路径,则完成查询所需的时间将是使用完整索引扫描时的10倍。