Оптимизация запросов SQL. Sql оптимизация запросов


Оптимизация запросов Sql Безопасный SQL

На данный момент я не так разбираюсь в TSql (писать с последних 4/5 месяцев), но я написал много запросов. Хотя я дал результаты, иногда я чувствую, что запросы не оптимизированы. Я искал в google и нашел много информации о оптимизации запросов, и они просят заглянуть в план запроса (фактический и оцененный) для импровизации производительности.

Как я уже сказал, я очень новичок в написании запросов, поэтому мне сложно понять эти решения. Но мне нужно изучить оптимизацию запросов.

Может ли какой-нибудь орган сначала помочь мне, как и с чего начать?

Поиск в Интернете показывает, что SEEK лучше, чем SCAN (пусть это индекс или таблица). Как я могу добиться поиска по сканированию?

Затем они говорят, что предложение ORDER BY, т.е. сортировка, является более дорогостоящим. Тогда в чем же дело? Как написать эффективный запрос?

Может ли кто-нибудь объяснить мне, с некоторыми примерами, какой вопрос лучше по сравнению с чем и в какой ситуации?

Вы все ответили, и это мне очень поможет. Но я хочу сказать, что вы все много практиковали для того, чтобы стать экспертом. Когда-то давно, я думаю, вы все были такими, какие я есть сейчас. Так что мой скромный запрос – это то, как вы все начали писать оптимизированный запрос. Я знаю, что требуется терпение, и я посвящу это. Прошу прощения за любой неправильный мой комментарий.

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

Поэтому вам нужно сначала изучить основы :

Следующие ссылки относятся к MS SQL Server. Если вы не используете СУБД, вы можете попробовать найти похожие материалы для выбранной вами системы. Фактически, пока вы понимаете, что реализация может отличаться, может быть полезно ознакомиться с документацией MS. Структуры хранения MS SQL MS SQL-страницы и экстенты

Затем, когда вы начали делать, изучите способ чтения планов запросов (даже если это не полностью понять вначале), и все это должно привести вас к тому уровню, на котором вы начнете понимать более продвинутые книги или статьи по этой теме. Я не знаю учебников для Query Plans в Интернете (хотя я уверен, что они существуют …), но может быть полезной следующая методология: Начните с простых запросов, просмотрите план запроса (если это возможно в графике мода), начните распознавать наиболее распространенные элементы: Сканирование таблицы, Поиск индекса, Сортировка, вложенные циклы … Прочитайте подробные свойства этих экземпляров: оцененный nb строк, процент затрат и т. д. Когда вы найдете новый элемент, который вы не используете знать / понимать, использовать это ключевое слово, чтобы найти информацию в Интернете. Также: экспериментируйте много.

Наконец, вы должны помнить, что, хотя способ написания запроса и набор индексов и т. Д. Обеспечивают большую часть потребностей оптимизации, существуют и другие источники optmization, например способ использования оборудования (основным примером является то, как имея файл данных и файл журнала на отдельных физических дисках, мы можем значительно улучшить производительность CRUD).

Поиск в Интернете показывает, что SEEK лучше, чем SCAN (пусть это индекс или таблица). Как я могу добиться поиска по сканированию?

Добавьте необходимый индекс – если дополнительные затраты на INSERT и UPDATE (и дополнительное хранилище) являются общей победой, чтобы ускорить поиск в ваших запросах.

Затем они говорят, что предложение ORDER BY, т.е. сортировка, является более дорогостоящим. Тогда в чем же дело? Как написать эффективный запрос?

Добавьте необходимый индекс – если дополнительные затраты на INSERT и UPDATE (и дополнительное хранилище) являются общей победой, чтобы ускорить заказ в ваших запросах.

Может ли кто-нибудь объяснить мне, с некоторыми примерами, какой вопрос лучше по сравнению с чем и в какой ситуации?

Вы уже указали несколько конкретных вопросов – и ответы были почти одинаковыми. Какая польза, чтобы добавить еще шесть?

Выполнять контрольные запросы по репрезентативным наборам искусственных данных (должны напоминать то, что вы планируете иметь в производстве), если у вас небольшие таблицы размером с игрушку, планы запросов не будут репрезентативными или значимыми), попробуйте с индексом, предлагать различные планы запросов, измерять производительность; промыть, повторить.

Практика занимает 10 000 часов, чтобы быть хорошими. Оптимизация схем БД, индексов, запросов и т. Д. Не является исключением ;-).

ORDER BY – необходимое зло – вокруг него нет никакого способа.

См. Этот вопрос для поиска поиска индекса, сканирования и поиска по закладкам / ключам . И этот сайт очень хорош для методов оптимизации …

Всегда убедитесь, что у вас есть индексы на ваших таблицах. Не слишком много и не слишком мало.

Используя SQL Server 2005, примените включенные столбцы в этих индексах, они помогают искать.

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

Всегда фильтруйте как можно раньше, если вы сокращаете количество соединений, вызовы функций и т. Д., Как можно раньше, вы сокращаете время, затрачиваемое на все

как всегда, нет жесткого правила, и все должно быть принято на основе запроса.

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

EDIT, чтобы комментировать вопрос:

Таблицы Temp могут использоваться, когда вам нужно добавлять индексы в таблицу temp (вы не можете добавлять индексы в таблицы var, кроме pk). В основном я использую таблицы var, когда могу, и у них есть только необходимые поля.

DECLARE @Table TABLE( FundID PRIMARY KEY )

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

На днях я прочитал несколько статей и, к моему удивлению, обнаружил, что таблицы var фактически созданы в tempdb

текст ссылки

Кроме того, я слышал и обнаружил, что таблица UDF может выглядеть как «черный ящик» для планировщика запросов. Еще раз, мы склонны перемещать выборки из функций таблицы в таблицы vars, а затем присоединяться к этим таблицам var. Но, как упоминалось ранее, сначала напишите код, а затем оптимизируйте, когда найдете бутылочные шейки.

Я обнаружил, что CTE могут быть полезны, но также, что, когда уровень рекурсии растет, он может быть очень медленным …

sql.fliplinux.com

optimization - Оптимизация запросов SQL

Я СЛУЧАЙНО переформатировал запрос для моей справки о удобочитаемости и лучше увидел отношения между таблицами... иначе проигнорирую эту часть.

SELECT g.name AS hostgroup, h.name AS hostname, a.host_id, s.display_name AS servicename, a.service_id, a.entry_time AS ack_time, ( SELECT ctime FROM logs WHERE logs.host_id = a.host_id AND logs.service_id = a.service_id AND logs.ctime < a.entry_time AND logs.status IN (1, 2, 3) AND logs.type = 1 ORDER BY logs.log_id DESC LIMIT 1) AS start_time, ar.acl_res_name AS timeperiod, a.state AS state, a.author, a.acknowledgement_id AS ack_id FROM centstorage.acknowledgements a LEFT JOIN centstorage.hosts h ON a.host_id = h.host_id LEFT JOIN centstorage.services s ON a.service_id = s.service_id LEFT JOIN centstorage.hosts_hostgroups p ON a.host_id = p.host_id LEFT JOIN centstorage.hostgroups g ON p.hostgroup_id = g.hostgroup_id LEFT JOIN centreon.hostgroup_relation hg ON a.host_id = hg.host_host_id LEFT JOIN centreon.acl_resources_hg_relations hh ON hg.hostgroup_hg_id = hh.hg_hg_id LEFT JOIN centreon.acl_resources ar ON hh.acl_res_id = ar.acl_res_id WHERE ar.acl_res_name != 'All Resources' AND YEAR(FROM_UNIXTIME( a.entry_time )) = YEAR(CURDATE()) AND MONTH(FROM_UNIXTIME( a.entry_time )) = MONTH(CURDATE()) AND a.service_id is not null ORDER BY a.acknowledgement_id ASC

Сначала я рекомендую начать с вашей таблицы "подтверждений" и иметь индекс как минимум (entry_time, confirmment_id). Затем обновите предложение WHERE. Поскольку вы используете функцию для преобразования временной отметки unix в дату и захвата YEAR (и месяца) соответственно, я не считаю, что она использует индекс, поскольку он должен вычислить это для каждой строки. Чтобы повысить это, временная метка unix представляет собой не что иное, как число, представляющее секунды из определенного момента времени. Если вы ищете определенный месяц, то предварительно вычислите начальное и конечное время unix и запустите для этого диапазона. Что-то вроде...

и a.entry_time >= UNIX_TIMESTAMP ('2015-10-01') и a.entry_time < UNIX_TIMESTAMP ('2015-11-01')

Таким образом, он составляет все секунды в течение месяца до 11:59:59 31 октября, незадолго до 1 ноября.

Тогда, без очков, чтобы увидеть все изображения более четко и короткое время сегодня утром, я бы обеспечил, чтобы у вас были по крайней мере следующие индексы на каждой таблице соответственно

table index logs ( host_id, service_id, type, status, ctime, log_id ) acknowledgements ( entry_time, acknowledgement_id, host_id, service_id ) hosts ( host_id, name ) services ( service_id, display_name ) hosts_hostgroups ( host_id, hostgroup_id ) hostgroups ( hostgroup_id, name ) hostgroup_relation ( host_host_id, hostgroup_hg_id ) acl_resources_hg_relations ( hh_hg_id, acl_res_id ) acl_resources ar ( acl_res_id, acl_res_name )

Наконец, ваше поле коррелированного подзапроса будет убийцей, поскольку оно обрабатывается для каждой строки, но, надеюсь, другие идеи оптимизации индекса помогут производительности.

qaru.site

performance - Оптимизация запросов Sql

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

Вот он:

select d.InvoiceDetailId,a.Fee,a.FeeTax from InvoiceDetail d LEFT JOIN InvoiceDetail a on a.AdjustDetailId = d.InvoiceDetailId

Я помещаю восходящий индекс в столбец AdjustDetailId

Затем я выполнил запрос с помощью "Показать фактический план выполнения", а оценочная стоимость поддерева (выпадающая из верхнего выбора node) была равна 2,07

Тогда я подумал, может быть, я могу что-то сделать, чтобы улучшить это, поэтому я добавил условное левое соединение так:

select d.InvoiceDetailId,a.Fee,a.FeeTax from InvoiceDetail d LEFT JOIN InvoiceDetail a on a.AdjustDetailId is not null and a.AdjustDetailId = d.InvoiceDetailId

Я снова запустил и получил стоимость поддерева 0,98. Поэтому я подумал, что я сделал это в два раза быстрее. Тогда я щелкнул статистику показа клиента, а затем щелкнул выполнить 4-5 раз с обоими запросами и полагаю, что это или нет первый запрос, усредненный, чтобы быть быстрее. Я не понимаю. Кстати, запрос возвращает 120 тыс. Строк.

Любое понимание?

Возможно, я получаю испорченные результаты из-за кэширования, но я не знаю, так ли это и как reset кэширование.

EDIT: Хорошо я googled, как очистить кеш запросов, поэтому я добавил следующее перед запросами:

DBCC DROPCLEANBUFFERS DBCC FREEPROCCACHE

Затем я выполнил каждый запрос 5 раз, и первый запрос был все еще немного быстрее (13%). 1-й запрос: время обработки клиента: 239.4 2-й запрос: время обработки клиента: 290

Итак, я думаю, вопрос в том, почему вы так думаете? Может быть, когда таблица в четыре раза больше, чем второй запрос будет быстрее? Или левое соединение вызывает запрос, который дважды попадает в индекс, поэтому он будет всегда медленнее.

Пожалуйста, не пламени меня, я просто пытаюсь получить образование.

ИЗМЕНИТЬ № 2: Мне нужно получить все InvoiceDetails, а не только скорректированные, следовательно, левое соединение.

ИЗМЕНИТЬ № 3: Реальная проблема, которую я пытаюсь решить с помощью запроса, состоит в том, чтобы суммировать все строки InvoiceDetail, но в то же время корректировать их. Поэтому в конечном итоге кажется, что лучший запрос для выполнения - это следующее. Я думал, что делать соединение, а добавление объединенного в таблицу будет единственным способом, но кажется, что группировка по условию решает проблему наиболее элегантно.

SELECT CASE WHEN AdjustDetailId IS NULL THEN InvoiceDetailId ELSE AdjustDetailId END AS InvoiceDetailId ,SUM(Fee + FeeTax) AS Fee FROM dbo.InvoiceDetail d GROUP BY CASE WHEN AdjustDetailId IS NULL THEN InvoiceDetailId ELSE AdjustDetailId END

Пример: со следующими строками InvoiceDetailID | Стоимость | FeeTax | AdjustDetailId

1 | 300 | 0 | NULL

2 | -100 | 0 | 1

3 | -50 | 0 | 1

4 | 250 | 0 | NULL

Мое желание состояло в том, чтобы получить следующее: InvoiceDetailID | Плата 1 | 150

4 | 250

Спасибо всем за ваш вклад.

qaru.site


Prostoy-Site | Все права защищены © 2018 | Карта сайта