2017-02-09 54 views
0

,我有以下形式的SQL表:检查是否在MySQL表中的两列相等太慢

| DateID | StartDate | EndDate | a lot more columns... 
|--------|-----------|----------|---------------------- 
| 1 |2017-02-09 |2017-02-16| ... 
| 2 |2017-02-10 | NULL | ... 
| 3 |2017-02-08 |2017-02-08| ... 

我经常遇到像Querys:

SELECT * FROM Dates 
WHERE (EndDate IS NULL AND StartDate<='some date') OR 
     (StartDate=EndDate AND StartDate>='some date' AND (other conditions)) 

因为表包含几个千条记录,这个查询相当慢。有没有办法加快这一点?例如,使用仅包含具有相同StartDate和EndDate的日期的视图? StartDate和EndDate已被定义为索引,但这对我猜测的“StartDate = EndDate”部分没有帮助。

在此先感谢! :)

+0

尝试创建2个querys避免'或' – SacrumDeus

+2

性能问题应该包括'EXPLAIN ANALYZE'和有关表的大小,指数,当前时间的一些信息表现,欲望时间等。“慢”是一个相对术语,我们需要真正的价值来比较。 \t \t [** MySQL **](http://dba.stackexchange.com/questions/15371/how-do-i-get-the-execution-plan-for-a-view) –

+0

MySQL index [ ** TIPS **](http://mysql.rjweb.org/doc.php/index_cookbook_mysql) –

回答

0

OR是你的问题。正因为如此,MySQL不能依赖日期索引并采取另一个(坏)路径,甚至是最坏的路径,进行全表扫描。

克服这种问题的一般解决方案是通过UNIONing几个查询来模拟OR

SELECT * FROM Dates WHERE (EndDate IS NULL AND StartDate<='some date') 
UNION ALL 
SELECT * FROM Dates WHERE (StartDate=EndDate AND StartDate>='some date' AND (other conditions)) 

对于这些查询中的每一个,MySQL都应该正确使用这些索引,这将会加速总执行时间的一个巨大因素。

OR在SQL中通常是邪恶的,应尽可能避免。

+0

谢谢,我一定会尝试! 但是“StartDate = EndDate”呢? MySQL不必为此做全表扫描吗? –

+0

不,如果您已正确索引这两列。 –

0

好的,谢谢你的帮助!我发现真正的问题在我的查询中甚至不是OR(尽管我现在使用Thomas G的建议对其进行了优化),但是这是在JOIN中使用的另一个表中的索引不太理想的情况。

所以感谢胡安·卡洛斯·Oropeza提供的链接MySQL indexing tips!