Нужны советы по оптимизации SQL-запросов с помощью JOIN - PullRequest
2 голосов
/ 31 марта 2009

Запрос, который я пишу, работает нормально, если посмотреть на последние несколько дней, а когда я прохожу больше недели, он ползет (~ 20 минут). Я объединяю 3 стола вместе. Мне было интересно, что я должен искать, чтобы сделать это быстрее. Я не знаю, какая еще информация нужна для публикации.

РЕДАКТИРОВАТЬ: Больше информации: db is Sybase 10. Запрос:

SELECT a.id, a.date, a.time, a.signal, a.noise,
b.signal_strength, b.base_id, b.firmware,
a.site, b.active, a.table_key_id
FROM adminuser.station AS a
JOIN adminuser.base AS b
ON a.id = b.base_id
WHERE a.site = 1234 AND a.date >= '2009-03-20'

Я также снял 3-ий JOIN, и он все еще работает очень медленно. Должен ли я попробовать другой метод JOIN?

Ответы [ 8 ]

2 голосов
/ 31 марта 2009

Вы можете получить много информации (при условии, что вы используете MSSQL здесь), запустив запрос в SQL Server Management Studio с параметром Включить фактический план выполнения Запрос меню).

Это покажет вам схему шагов, которые SQLServer выполняет для выполнения запроса - с относительными затратами на каждый шаг.

Следующий шаг - немного переработать запрос (попробуйте сделать это по-другому), затем запустить новую версию и старую одновременно. Вы получите два плана выполнения с относительными затратами не только на каждый шаг, но и на две версии запроса! Таким образом, вы можете объективно сказать, если вы делаете успехи.

Я делаю это все время при отладке / оптимизации запросов.

2 голосов
/ 31 марта 2009

Я не очень хорошо знаю Sybase 10, но попробуйте выполнить этот запрос, скажем, для 10-дневного периода, а затем 10 раз для каждого дня в периоде соответственно и сравните время. Если время в первом случае намного выше, вы, вероятно, достигли пределов кэша базы данных.

Решение состоит в том, чтобы просто выполнять запросы для более коротких периодов в цикле (в программе, а не в SQL). Это особенно хорошо работает, если таблица A разбита по дате.

1 голос
/ 31 марта 2009

Убедитесь, что у вас есть индексы для внешних ключей.

0 голосов
/ 01 апреля 2009
SELECT

 a.id, a.date, a.time, a.signal, a.noise,a.site, b.active, a.table_key_id,
 b.signal_strength, b.base_id, b.firmware

FROM 

( SELECT * FROM adminuser.station 
      WHERE site = 1234 AND date >= '2009-03-20') AS a
JOIN 

    adminuser.base AS b
ON

    a.id = b.base_id

Вид переписанного запроса, чтобы сначала отфильтровать нужные строки, затем выполнить объединение, а не выполнить объединение, а затем отфильтровать результат.

Вместо того, чтобы извлекать * из подзапроса, вы можете просто выбрать нужные столбцы, что может оказаться мало полезным.

Может быть, это мало поможет в ускорении вещей.

Хотя это допустимо в MySql, я не уверен в синтаксисе sysbase.

0 голосов
/ 31 марта 2009

Вы не упомянули свою базу данных. Если это не SQL Server, особенности получения данных могут отличаться, но в основном это тот же совет.

Обязательно посмотрите на индексирование, но в первую очередь следуйте советам Blorgbeard и сканируйте планы выполнения с помощью Management Studio (опять же, если вы используете SQL Server).

Я предполагаю, что вы увидите, что для небольших диапазонов дат оптимизатор выбирает разумный план запроса, но когда диапазон дат большой, он выбирает что-то совершенно иное, вероятно, включающее либо сканирование таблицы, либо сканирование индекса и, возможно, объединения, которые приводят к очень большим временным наборам записей. Анализатор плана выполнения покажет все это.

Сканирование означает, что оптимизатор считает, что просмотр всей таблицы или всего индекса дешевле того, что вы пытаетесь сделать, чем поиск конкретных значений.

То, что вы в конечном итоге захотите сделать, - это получить индексы и синтаксис вашего запроса, настроенный таким образом, чтобы вы сохраняли поиск индекса в плане запроса для вашего запроса независимо от диапазона дат, или, если это не удалось, то требуемые сканы отфильтрованный, а также вы можете минимизировать размер временного набора записей и тем самым избежать чрезмерного чтения и ввода-вывода.

0 голосов
/ 31 марта 2009

Захватите книгу "Профессиональная настройка производительности SQL Server 2005" - это здорово.

0 голосов
/ 31 марта 2009

Возможно, вы захотите изучить использование PARTITION для диапазонов дат, если ваша БД поддерживает это. Я слышал, это может значительно помочь.

0 голосов
/ 31 марта 2009

Звучит так, будто у вас утечка памяти или вы не закрываете соединения с базой данных в своем клиентском коде, чем то, что в запросе что-то не так.

[править]
Неважно: вы имеете в виду запросы по диапазону дат, а не по продолжительности работы сервера. Я оставлю это, чтобы помочь другим избежать той же путаницы.

Кроме того, было бы полезно, если бы вы могли опубликовать SQL-запрос, даже если вам сначала нужно его запутать, и это хорошая ставка, чтобы проверить, есть ли индекс в столбце даты и количество записей, возвращенных более длинным диапазон.

...