4

所以我必须处理一个没有索引的数据库(不是我的设计,这让我很沮丧)。我正在运行一个大约需要三秒钟才能返回的查询,我需要它更快。

以下是相关的表格和列:

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 秒)。任何想法将不胜感激。

4

4 回答 4

12

没有索引,你会被淹没。数据库引擎每次都必须进行全表扫描。摆弄这些问题只是重新安排泰坦尼克号上的躺椅。现在修复数据库,以免随着数据的堆积而变得更糟。

于 2011-08-25T16:04:55.993 回答
5

查询也可以不使用 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
于 2011-08-25T16:51:55.943 回答
2

由于您无法在表上创建索引...您是否有权创建索引视图?

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

这会给你索引的好处,但不会改变原始表......

于 2011-08-25T17:06:06.393 回答
1

您可以尝试以下方法,我不知道您还能做什么,或者这是否会使它变得更快:/

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
于 2011-08-25T16:24:49.063 回答