|
11.01.2008, 12:25 | #1 |
MCTS
|
LIKE VS EXISTS JOIN
Всем превед!
Представим следующую ситуацию: есть табличка LedgerTrans с большим количеством записей (порядка 500 тыс.). Соответственно нужно выбрать из нее только записи, у которых счет равен 10.100 и 10.200. Внимание - вопрос! Какой запрос отработает быстрее? 1. select LedgerTrans exist join param where LedgerTrans.AccountNum == param.AccountNum (param - табличка, в которой перечислены нужные счета, в нашем случае 10.100 и 10.200). 2. select LedgerTrans where LedgerTrans.AccountNum like "10.*" Последний раз редактировалось CDR; 11.01.2008 в 12:38. |
|
11.01.2008, 12:27 | #2 |
Участник
|
А если взять да попробовать?
|
|
11.01.2008, 12:35 | #3 |
MCTS
|
|
|
11.01.2008, 12:28 | #4 |
Участник
|
А так
X++: select LedgerTrans where LedgerTrans.AccountNum >= "10." && LedgerTrans.AccountNum <= "10.Я" // или LedgerTrans.AccountNum < "10<соедующий символ после точки>" |
|
11.01.2008, 12:39 | #5 |
Участник
|
Доп вопросы:
1. Какое число записей в LedgerTrans соответствуют условию ? 2. Какие индексы есть на таблице LedgerTrans ? 3. Таблица Param постоянная или временная ? 4. Какие индексы есть на таблице Param ? 5. Какое выравнивание у поля LedgerTrans.AccountNum, влево или вправо ? |
|
11.01.2008, 12:35 | #6 |
Участник
|
Если по AccountNum есть индекс, то с точки зрения SQL - like будет меньше ресурсов потреблять чем join. И потом exist join не факт что будет 1 запросом работать на сервере.
|
|
11.01.2008, 12:40 | #7 |
MCTS
|
Больше интересует скорость исполнения, а не потребляемые ресурсы. Что выполниться быстрее: построится join или просканируется like?
|
|
11.01.2008, 12:46 | #8 |
Участник
|
|
|
11.01.2008, 12:55 | #9 |
Участник
|
Цитата:
Сообщение от CDR
Всем превед!
Представим следующую ситуацию: есть табличка LedgerTrans с большим количеством записей (порядка 500 тыс.). Соответственно нужно выбрать из нее только записи, у которых счет равен 10.100 и 10.200. Внимание - вопрос! Какой запрос отработает быстрее? 1. select LedgerTrans exist join param where LedgerTrans.AccountNum == param.AccountNum (param - табличка, в которой перечислены нужные счета, в нашем случае 10.100 и 10.200). 2. select LedgerTrans where LedgerTrans.AccountNum like "10.*" |
|
11.01.2008, 12:59 | #10 |
MCTS
|
|
|
11.01.2008, 13:00 | #11 |
Участник
|
tourist, я полагаю теоретически вариант 2. быстрее, так как SQL в 1. варианте не знает, что можно обойтись index scan по AccountNum, и в 1 варианте сначала сделать tableScan по param, потом nestedLoop по всем записям и indexSсan по LedgerTranns
|
|
11.01.2008, 13:32 | #12 |
MCTS
|
Хм... Только что опробовал обе конструкции на тестовой табличке с количеством записей около 200 тыс. Результат поразил, однако...
Конструкция с exist join выигрывает в скорости более чем в 10 раз Ваши каменты по этому поводу? |
|
11.01.2008, 14:15 | #13 |
Модератор
|
Цитата:
Например, запрос в QA без фильтра на DataAreaId ну и опять же метания между Цитата:
в нашем случае 10.100 и 10.200)
Цитата:
where LedgerTrans.AccountNum like "10.*"
покажи (ничего, что я на ТЫ? ) запросы и планы
__________________
-ТСЯ или -ТЬСЯ ? |
|
11.01.2008, 14:25 | #14 |
Участник
|
Думаю, что Join быстрее при наличии индекса, так как с Like он не используется
|
|
11.01.2008, 14:39 | #15 |
Участник
|
|
|
11.01.2008, 14:49 | #16 |
MCTS
|
|
|
11.01.2008, 13:40 | #17 |
Участник
|
А планчики можно?
А мой вариант? |
|
11.01.2008, 13:55 | #18 |
Участник
|
Честно говоря, тоже думал, что второй будет работать быстрее.
Особенно учитывая, что у LedgerTrans есть индекс, где первым полем идет AccountNum. Планы бы действительно интересно было посмотреть. |
|
11.01.2008, 14:39 | #19 |
Участник
|
select LedgerTrans where LedgerTrans.AccountNum >= "10."
&& LedgerTrans.AccountNum < "10/" |
|
11.01.2008, 14:47 | #20 |
MCTS
|
|
|