SQL查询慢,不知道如何优化
Posted
技术标签:
【中文标题】SQL查询慢,不知道如何优化【英文标题】:Slow SQL query, not sure how to optimize 【发布时间】:2011-08-25 16:00:43 【问题描述】:所以我必须处理一个没有索引的数据库(不是我的设计,这让我很沮丧)。我正在运行一个大约需要三秒钟才能返回的查询,我需要它更快。
以下是相关的表格和列:
gs_pass_data au_entry ground_station
-gs_pass_data_id -au_id -ground_station_id
-start_time -gs_pass_data_id -ground_station_name
-end_time -comments
-ground_station_id
我的查询是:
SELECT DISTINCT gs_pass_data_id,start_time,end_time,
ground_station_name FROM gs_pass_data
JOIN ground_station
ON gs_pass_data.ground_station_id =
ground_station.ground_station_id
JOIN au_entry ON au_entry.gs_pass_data_id =
gs_pass_data.gs_pass_data_id
WHERE (start_time BETWEEN @prevTime AND @nextTime)
AND comments = 'AU is identified.'
ORDER BY start_time
我尝试使用 EXISTS 代替 DISTINCT,但没有任何改进。我已经阅读了有关 SQL 优化的所有内容,但我似乎无法将此查询缩短到合理的时间(合理的时间小于 0.5 秒)。任何想法将不胜感激。
【问题讨论】:
使用EXISTS
是唯一可用的语法优化。您需要添加一些索引!
您有 NO INDEXES,无法添加任何索引?这是谁的设计,你怎么能绕过它们?
我害怕这个。不幸的是,我只是一名合作学生,对此没有任何发言权。非常令人沮丧。
索引是提高速度的最佳方法。删除 ORDER BY 可能会有所帮助。
好@乔恩。从表中归档一些记录怎么样?如果您必须进行全表扫描,那么减少记录数可能会有所帮助。
【参考方案1】:
没有索引,你会被淹没。数据库引擎每次都必须进行全表扫描。摆弄这些问题只是重新安排泰坦尼克号上的躺椅。立即修复数据库,以免随着数据堆积而变得更糟。
【讨论】:
是的,我意识到了这一点。我无法控制数据库,但我会尝试与某人联系。 同意 - 索引将是影响您的表现的最佳选择。 (从好的方面来说,至少数据集看起来很小,如果运行该查询只需要 3 秒)。【参考方案2】:查询也可以不用 distinct 而用 group by 代替。不过,它可能根本没有区别。标准建议与其他所有人的建议相同。添加索引,删除 'order by' 所以 +1 到 @Marc B
SELECT gs_pass_data_id,start_time,end_time,ground_station_name
FROM gs_pass_data
JOIN ground_station
ON gs_pass_data.ground_station_id = ground_station.ground_station_id
JOIN au_entry
ON au_entry.gs_pass_data_id = gs_pass_data.gs_pass_data_id
WHERE (start_time BETWEEN @prevTime AND @nextTime)
AND comments = 'AU is identified.'
GROUP BY gs_pass_data_id,start_time,end_time,ground_station_name
ORDER BY start_time
【讨论】:
如果您将 Au 被识别位包装在 nvarchar 中,它应该会使其更快一点,因为您没有隐式转换。例如。N'Au is...'
这真的加快了速度吗?它应该几乎没有任何区别,甚至可能会减慢速度。
我还没来得及测试它。但是我在这里开始了讨论:dba.stackexchange.com/questions/5038/in-memory-performance【参考方案3】:
由于您不能在表上创建索引...您是否有权创建索引视图?
SQL 2005 - http://technet.microsoft.com/en-us/library/cc917715.aspx
SQL 2008 - http://msdn.microsoft.com/en-us/library/dd171921(v=sql.100).aspx
这会给您带来索引的好处,但不会改变原始表...
【讨论】:
【参考方案4】:您可以尝试以下方法,我不知道您还能做什么,或者这是否会让它变得更快:/
SELECT DISTINCT gs_pass_data_id,start_time,end_time,ground_station_name
FROM
(
-- My idea is to make this first table as small as possible first, which will then make the joins quicker (TM)
SELECT *
FROM gs_pass_data
WHERE (start_time BETWEEN @prevTime AND @nextTime)
) t
INNER JOIN ground_station ON gs_pass_data.ground_station_id = ground_station.ground_station_id
INNER JOIN
(
-- Same as above
SELECT *
FROM au_entry
WHERE comments = N'AU is identified.' -- Make sure comments is the same type as the text string. You said nvarchar so make the string your searching by nvarchar
) t2 ON au_entry.gs_pass_data_id = gs_pass_data.gs_pass_data_id
ORDER BY start_time
-- OR TRY THIS
SELECT DISTINCT gs_pass_data_id,start_time,end_time,ground_station_name
FROM
(
-- My idea is to make this first table as small as possible first, which will then make the joins quicker (TM)
SELECT *
FROM gs_pass_data
WHERE (start_time BETWEEN @prevTime AND @nextTime)
) t
INNER JOIN ground_station ON gs_pass_data.ground_station_id = ground_station.ground_station_id
INNER JOIN au_entry ON au_entry.gs_pass_data_id = gs_pass_data.gs_pass_data_id
WHERE comments = N'AU is identified.' -- Make sure comments is the same type as the text string. You said nvarchar so make the string your searching by nvarchar
ORDER BY start_time
【讨论】:
这些查询都给我“无法绑定多部分标识符”错误。 所有需要做的就是将选择替换为t.gs_pass_data_id,t.start_time,t.end_time,ground_station_name
以上是关于SQL查询慢,不知道如何优化的主要内容,如果未能解决你的问题,请参考以下文章