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查询慢,不知道如何优化的主要内容,如果未能解决你的问题,请参考以下文章

如何优化我的 SQL 查询?

MySQL如何定位并优化慢查询sql

sql查询速度慢如何优化

mysql慢查询

如何进行SQL性能优化

第15天SQL进阶-查询优化-慢查询日志(SQL 小虚竹)