我有一个有效的查询,但速度很慢。有没有办法加快速度?基本上我有一个带有时间卡条目的表,然后是第二个表,其中包含该条目的时间细分,与TimecardID相关。我正在寻找的是没有故障的时间块。我想如果我将标准降低到2个月就可以加快速度。谢谢你的帮助
SELECT * FROM Timecards
WHERE NOT EXISTS (SELECT TimeCardID FROM TimecardBreakdown WHERE Timecards.ID = TimecardBreakdown.TimeCardID)
AND Status <> 0
AND DateIn >= CURRENT_DATE() - INTERVAL 2 MONTH
答案 0 :(得分:2)
您似乎想知道TimecardBreakdown表中不存在的TimecardID,在这种情况下,您可以使用左外连接。
SELECT a.*
FROM Timecards a
LEFT OUTER JOIN TimecardBreakdown b ON a.TimecardID = b.TimecardID
WHERE b.TimecardID IS NULL
这将摆脱子查询(这是昂贵的)并使用连接(这是更有效的)。
答案 1 :(得分:0)
MySQL很快就会发现相关的子查询。尝试使子查询独立并加入它们。您可以使用LEFT JOIN ... IS NULL
模式替换WHERE NOT EXISTS
。
SELECT tc.*
FROM Timecards tc
LEFT JOIN TimecardBreakdown tcb ON tc.ID = tcb.TimeCardId
WHERE tc.DateIn >= CURRENT_DATE() - INTERVAL 2 MONTH
AND tc.Status <> 0
AND tcb.TimeCardId IS NULL
一些优化点。
首先,如果您可以将tc.Status <> 0
更改为tc.Status > 0
,则可以在该列上进行索引范围扫描。
其次,当您优化内容时,SELECT *
被认为是有害的。相反,如果您可以只提供所需列的名称,事情就会更快。数据库服务器必须绕过您要求的所有数据;它无法判断你是否会忽略其中一些。
第三,Timecards (DateIn, Status, ID)
上的复合索引将有助于此查询。该复合索引可用于满足您的查询条件的繁重生命。
这称为覆盖索引;它包含满足您的大部分查询所需的数据。如果您仅为DateIn
列编制索引,则查询处理程序必须退回到主表以查找Status
和ID
的值。当这些列出现在索引中时,它会保存额外的操作。
如果您SELECT
某列而不是SELECT *
,那么包括覆盖索引中的那些列可以显着提高查询性能。这是SELECT *
被认为有害的几个原因之一。
(DBMS的一些品牌和型号有办法指定列表的列表,而不是实际索引它们.MySQL需要你索引它们。但覆盖索引仍然有帮助。)