Медленный SQL-запрос, не уверен, как оптимизировать - PullRequest
3 голосов
/ 25 августа 2011

Так что мне приходится иметь дело с базой данных, у которой нет индексов (не мой дизайн, это чертовски расстраивает меня). Я выполняю запрос, который занимает приблизительно три секунды, и мне нужно, чтобы он был быстрее.

Вот соответствующие таблицы и столбцы:

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 секунды). Любые идеи будут с благодарностью. </p>

Ответы [ 4 ]

11 голосов
/ 25 августа 2011

Без индексов, вы прокляты. Механизм БД должен будет выполнять полное сканирование таблицы каждый раз, каждый раз. Возиться с вопросами просто переставить шезлонги на Титанике. Исправьте БД сейчас, пока она не стала еще хуже по мере накопления данных.

4 голосов
/ 25 августа 2011

Запрос также может быть написан без отдельного и с группой вместо.Это, вероятно, не будет иметь никакого значения, хотя.Стандартный совет такой же, как и у всех остальных.Добавьте индексы, отбросьте 'порядок на`, чтобы +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
2 голосов
/ 25 августа 2011

Поскольку вы не можете создавать индексы для таблиц ... есть ли у вас полномочия на создание индексированных представлений?

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

Это даст вам выгоду от индексов, но не изменит исходные таблицы ...

1 голос
/ 25 августа 2011

Вы можете попробовать следующее, я не знаю, что еще вы можете сделать, или если это вообще сделает это быстрее: /

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
...