Когда стоит вопрос: использовать
LEFT или LIKE - надо брать второе. Особенно в базах, которые поддерживают индексацию в LIKE.💳Пример - есть таблица с номерами карт, этот столбец индексирован, и мы хотим вытащить все MasterCard (начинаются на 5).
Какие есть варианты запроса?
SELECT * FROM accounts
WHERE LEFT(account_num, 1) = '5'
SELECT * FROM accounts
WHERE account_num LIKE '5%'
План запроса:
|--Clustered Index Scan(..., WHERE:(substring(account_num,(1),(1))=N'5'))
|--Clustered Index Seek(..., SEEK:(account_num >= N'5' AND account_num < N'6'), WHERE:(account_num like N'5%') ORDERED FORWARD)
🔫В первом случае мы убиваем навешенный индекс, потому что под капотом лежит
Index Scan - вытаскиваем все строки из таблицы и ищем совпадение с подстрокой.🔎Во втором случае под капотом уже
Index Seek - сразу вытаскиваем нужную группу записей, потом фильтруем.PROFIT👍
Проблема в использовании функций. Поэтому, если возможно, заменяйте функции поверх полей на операторы, чтобы индексы могли нормально работать:
SELECT * FROM documents
WHERE YEAR(valid_from) = 2023 and MONTH(valid_from) = 6
--Index Scan
SELECT * FROM documents
WHERE valid_from BETWEEN '2023-06-01' AND '2023-06-30'
--Index Seek 👍
#sql_tips