Какой из этих двух запросов более эффективен? - PullRequest
0 голосов
/ 27 марта 2012

У меня есть следующие два запроса, я считаю, что тот, который использует три сканирования индекса (второй), а не полный, более эффективен, но мне нужно больше мнений. Кроме того, как я могу получить один счет из трех счетчиков во втором запросе? Как я могу объединить их в один?

Первый запрос

SELECT count(*) FROM bldng 
WHERE (bldng_type LIKE '%PTR%' OR bldng_type LIKE '%FACILITY-A%' 
OR bldng_type LIKE '%FACILITY-B%') AND area_sqf > 500

Второй запрос

SELECT count(*) FROM bldng WHERE bldng_type LIKE '%PTR%' AND area_sqf > 500 
UNION ALL
SELECT count(*) FROM bldng WHERE bldng_type LIKE '%FACILITY-A%' AND area_sqf > 500  
UNION ALL
SELECT count(*) FROM bldng WHERE bldng_type LIKE '%FACILITY-B%' AND area_sqf > 500

Хорошо, это результат, который я получил после того, как запустил оба запроса с 'set statistics io on'

Первый (однострочный) запрос:

Category    Timestamp   Duration    Message Line    Position
Connection  3/27/2012 2:36:49 PM        3615: Table 'bldng'. Scan count 1, logical  reads 33320, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.   1   0

Второй запрос:

Category    Timestamp   Duration    Message Line    Position
Connection  3/27/2012 2:38:15 PM        3615: Table 'bldng'. Scan count 15, logical reads 76703, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.   1   0

Category    Timestamp   Duration    Message Line    Position
Connection  3/27/2012 2:38:15 PM        3615: Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.    1   0

Хотя я не уверен, как это интерпретировать. Сравнивать ли логические чтения 33320 <76703? То есть у первого меньше, значит ли это, что он работает более эффективно? </p>

Ответы [ 3 ]

2 голосов
/ 27 марта 2012

Прежде всего, ни одно из написанных вами утверждений не использует индекс для столбца bldng_type. LIKE Сравнения с подстановочными знаками в начале строки не оптимизируются.

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

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

Наконец, «идеальный» механизм базы данных сведет все семантически идентичные запросы к одному и тому же оптимизированному плану запросов. Это невозможно в случае, который вы цитировали, поскольку запросы на самом деле дают разные результаты. Но если вы написали запросы так, чтобы они были узнаваемо одинаковыми, они (опять же, в идеальном ядре базы данных) должны выполняться за одинаковое количество времени.

0 голосов
/ 27 марта 2012

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

0 голосов
/ 27 марта 2012

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

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

Когда вы говорите "использует 3 индекса" - вы построили 3 разных индекса для столбца bldng_type?

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

Если вы запустите второй, он может попытаться запросить таблицу 3 раза, а затем объединить результаты.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...