Подсказка (SQL)
Подсказка в языке SQL (англ. hint) — средство, позволяющее явным образом влиять на план запроса.
Сам SQL-запрос содержит указание, какую информацию необходимо получить из базы данных, но не содержит указаний, каким образом это делать. В общем случае, реляционные СУБД по собственным правилам определяют план запроса и, соответственно, его выполняют. Однако на практике может возникнуть случай, что такой план запроса, в силу неучтённых средствами СУБД факторов, несовершенства логики или особых требований может оказаться неоптимальным. Подсказка позволяет явно вмешаться в формирование плана запроса, не полагаясь полностью на автоматику.
Синтаксис и набор подсказок не описан в стандарте SQL, он сильно зависит от конкретной реализации СУБД.
Выделяются следующие назначения подсказок:
- указание порядка соединения таблиц,
- указание метода соединения таблиц,
- указание конкретного индекса для доступа к таблице.
В некоторых случаях СУБД может проигнорировать подсказку.
Реализационные особенности
Microsoft SQL Server
В Microsoft SQL Server добавлены некоторые ключевые слова для подсказок оптимизатору, например, в запросе:
SELECT *
FROM Customers C WITH (INDEX=City)
INNER LOOP JOIN Orders O ON O.CustomerID = C.CustomerID
WHERE C.City = 'Madrid'
фигурируют две подсказки:
LOOP
— указывает, что соединять таблицы следует методом вложенных цикловWITH (INDEX=City)
— указывает, что для доступа к таблице Customers следует использовать индекс с названием City
Oracle Database
В Oracle Database подсказки вставляются в текст запроса как комментарий. Текст комментария анализируется и, если обнаруживается, что он соответствует синтаксису языка подсказок, он принимается. Благодаря такому синтаксису, запрос с подсказками может выполняться на другой СУБД без модификации, а опечатка в подсказке приводит к тому, что подсказка рассматривается сервером как простой комментарий[1]. Например, в запросе:
SELECT /*+ full(t) */ t.name FROM tbl1 t WHERE t.date = SYSDATE
SELECT /*+ index(t ind_date) */ t.name FROM tbl1 t WHERE t.date = SYSDATE
использованы следующие подсказки:
/*+ full(t) */
— указывает, что поиск нужно вести сканированием всей таблицы/*+ index(t ind_date) */
— указывает, что поиск нужно вести по конкретному индексу