Общие правила (советы) написания запросов на SQL


Несмотря на то, что все реляционные СУБД имеют встроенный оптимизатор, существуют общие правила, которым стоит придерживаться при создании запросов:

1) Никогда не следует выполнять вычислений на индексированном столбце, например WHERE Amt*5 > : Value

2) Для отключения индекса следует использовать выражения: CName||”, CNum+0 или использовать функцию от значения столбца.

3) Вместо оператора OR предпочтительно использовать оператор UNION.

4) Вместо ключевых слов NOT IN лучше использовать оператор NOT EXISTS.

5) Нельзя допускать значение NULL в индексированном столбце.

6) Не следует использовать оператор LIKE, если достаточно оператора =.

7) Не следует использовать подзапросы, если можно обойтись соединением таблиц JOIN.

8) При объединении таблиц в разделе FROM запроса их следует указывать в порядке уменьшения числа выбираемых из них строк (для продукционного оптимизатора).

9) При ссылке на столбцы при объединении таблиц используйте псевдонимы таблиц.

10) Наибольшее ограничение на выборку строк в разделе WHERE должно стоять первым, если условие выборки включает оператор OR и последним, если содержит только операторы AND (для продукционного оптимизатора).

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

12) Используйте полный просмотр, если запрос возвращает более 20% строк из таблиц.

13) В СУБД Oracle8 можно использовать с помощью подсказки /*+INDEX_EFS*/ индексный полный просмотр (EFS), если индекс содержит все столбцы, требуемые в запросе

Простые запросы могут быть написаны самыми различными способами.

Рассмотрим запрос, возвращающий имена всех покупателей, сделавших заказы 10 марта 1990 года.

Варианты реализации запросов:
1) Запрос с объединением таблиц

SELECT DISTINCT CName FROM Customer INNER JOIN Orders ON Orders.CNum=Customer.CNum WHERE Odate=10/03/1990

2) Запрос с коррелируемым подзапросом

SELECT DISTINCT CName FROM Customer WHERE 0<(SELECT COUNT(*) FROM Orders WHERE Odate=10/03/1990 AND Orders.CNum=Customer.CNum)

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


Комментарии запрещены.




Статистика