Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности

Новые сообщения [новые:0]
Дайджест
Горячие темы
Избранное [новые:0]
Форумы
Пользователи
Статистика
Статистика нагрузки
Мод. лог
Поиск
|
|
15.02.2018, 08:38
|
|||
|---|---|---|---|
|
|||
Не задействуется индекс - прошу помочь с поиском причины |
|||
|
#18+
Добрый день! Уже очень давно не имела дело с СУБД, возможно забыла какую-то базовую вещь, прошу подсказать. Есть запрос такого вида: select flt.id, bt_child.value1, bt_child.value2, bt.fieldbt from BigTable bt // таблица примерно на 3-4 млн записей с кластерным индексом по id inner join #SmallTable flt // временная таблица примерно на 10-20 тыс записей, неиндексирована on flt.id= bt.id_contract // поле id_contract таблицы bt - индексировано inner join BigTable_Child bt_child // таблица примерно на 300 млн записей с кластерным индексом по id on bt_child .id_subcontract= bt.id // поле id_subcontract таблицы bt - индексировано where bt_child.stringfield in('string1','string2') // поле stringfield - не индексировано. запрос выполняется долго (десятки минут). План запроса показывает, что что индекс по полю bt_child .id_subcontract не задействован, вместо него используется кластерный индекс BigTable_Child.id, и эта операция дает 95% стоимости запрос. Рекомендует создание индекса по полю bt_child.stringfield. Но этого делать бы не хотелось, так как для таблицы критично время вставки. Я думала, что индекса по полю bt_child .id_subcontract будет достаточно. Что я не учла? В чем может быть проблема? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
15.02.2018, 08:43
|
|||
|---|---|---|---|
|
|||
Не задействуется индекс - прошу помочь с поиском причины |
|||
|
#18+
Прошу прощения - забыла тег. Поправляюсь. Код: sql 1. 2. 3. 4. 5. 6. 7. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
15.02.2018, 09:10
|
|||
|---|---|---|---|
|
|||
Не задействуется индекс - прошу помочь с поиском причины |
|||
|
#18+
Kateryne, всё правильно сервер сделал.... у тебя никаких условий фильтрации по индексным полям нет. соответственно, ему всё одно придется перебрать все строки. Логично, что он начал с чтения кластерного индекса по самой большой таблицы.... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
15.02.2018, 09:18
|
|||
|---|---|---|---|
|
|||
Не задействуется индекс - прошу помочь с поиском причины |
|||
|
#18+
Kateryne, и пока не пришли остальные адепты... статистика по таблицам-индексам - актуальна ? индексы не фрагментированы в лоскуты-клочья? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
15.02.2018, 13:13
|
|||
|---|---|---|---|
|
|||
Не задействуется индекс - прошу помочь с поиском причины |
|||
|
#18+
Kateryne, select a,s,c from table1 join table2 on table1.id = table2.id with (index(indexname), nolock) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
15.02.2018, 18:39
|
|||
|---|---|---|---|
|
|||
Не задействуется индекс - прошу помочь с поиском причины |
|||
|
#18+
Добрый Э - ЭхKateryne, всё правильно сервер сделал.... у тебя никаких условий фильтрации по индексным полям нет. соответственно, ему всё одно придется перебрать все строки. Логично, что он начал с чтения кластерного индекса по самой большой таблицы.... Спасибо за ответ! Но не совсем поняла - у меня собственно и был вопрос, почему оптимизатор в данном случае не хочет сначала использовать условие соединения в выборке по индексированному полю (это дало бы 10-20 тыс строк), а потом по ним уже фильтровать по неиндексированному? Я же правильно помню, что при inner join порядок - что будет раньше - where или join - выбирает оптимизатор? Или ошибаюсь? Статистика актуальна, индекс по полю id_subcontract создан с нуля, так что по идее не должен быть расплющен по диску. Но - вообще где-то в этом направлении проблема может быть, так как данные в этой большой таблице на 300 млн перезаливались с нуля с другой такой же большой таблицы с почти такой же структурой. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
15.02.2018, 18:40
|
|||
|---|---|---|---|
|
|||
Не задействуется индекс - прошу помочь с поиском причины |
|||
|
#18+
Гость, проходящий мимоKateryne, select a,s,c from table1 join table2 on table1.id = table2.id with (index(indexname), nolock) спасибо! можно и так попробовать, сделаем завтра тест, но хотелось бы понять первопричину без подобных хитростей... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
15.02.2018, 18:45
|
|||
|---|---|---|---|
Не задействуется индекс - прошу помочь с поиском причины |
|||
|
#18+
KateryneГость, проходящий мимоKateryne, select a,s,c from table1 join table2 on table1.id = table2.id with (index(indexname), nolock) спасибо! можно и так попробовать, сделаем завтра тест, но хотелось бы понять первопричину без подобных хитростей... получите ещё один лукап в теории если менть ничего не хотите OPTION(FORCE ORDER) может помочь ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
15.02.2018, 19:25
|
|||
|---|---|---|---|
|
|||
Не задействуется индекс - прошу помочь с поиском причины |
|||
|
#18+
Kateryne, ты же не показала план запроса, как можно говорить что-то более конкретно? (а если будешь показывать, то лучше не картинку, как это делают некоторые, а полный xml вложи к сообщению) но на правах метода "пальцем в небо" предположу - возможно, сервер ошибается в оценке кардинальности множеств сходу не вспомню, поэтому придется тебе самой почитать - как оценивает сервер количество строк во временной таблице... Видимо, он не понимает, что у тебя там именно 10-20 т. строк, а не одна или не миллион.... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
15.02.2018, 20:28
|
|||
|---|---|---|---|
Не задействуется индекс - прошу помочь с поиском причины |
|||
|
#18+
Kateryne Код: sql 1. Ничего не путаете? Может все-таки таблицы bt_child? Индекс сделайте на bt_child как (id_subcontract) include (value1, value2) Если просто по id_subcontract, то потребуется Key Lookup, чтобы достать value1, value2 из таблицы. А это дорогая операция. Чтобы убедиться, можете сравнить финальную стоимость запроса в оценочных планах для Код: sql 1. 2. 3. 4. 5. 6. 7. и Код: sql 1. 2. 3. 4. 5. 6. 7. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
15.02.2018, 20:35
|
|||
|---|---|---|---|
|
|||
Не задействуется индекс - прошу помочь с поиском причины |
|||
|
#18+
invmНичего не путаете? Может все-таки таблицы bt_child? [/quot] Да, конечно - опечаталась. Тогда всем спасибо большое за советы, завтра попробую - сейчас доступа нет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
15.02.2018, 21:29
|
|||
|---|---|---|---|
Не задействуется индекс - прошу помочь с поиском причины |
|||
|
#18+
Добрый Э - Эх, Да даже если сервер не ошибается, то очень грубо это будет примерно так: 1. Отношение BigTable к BigTable_Child примерно 1 к 75 (4 млн/300 млн) 2. Отношение BigTable к #SmallTable - 1 к 1? Сомневаюсь. id_contract выглядит как внешний ключ, скорее всего неуникальный. Ну предположим, что 1 к 1. 3. Итого 20К строк из BigTable превращаются в 20К*75 = 1.5 млн BigTable_Child 4. И теперь нам нужно сделать 1.5 млн лукапов. Что уже достаточно много, и полный скан скорее всего предопчтителен. 5. Ну и совсем уже пальцем в небо: если предположить что 1 строка в BigTable_Child занимает 500 байт, то всего на странице может быть максимум 16 строк, получается 18,750,000 страниц на листовом уровне. Если же делать лукапы то нужно прочитать 1.5 млн x 4 = 6 млн страниц. По сравнению с полным сканом это 32%, что достаточно много чтобы сервер выбрал поиск по индексу + лукап. Скан дешевле. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|

start [/forum/topic.php?fid=46&tablet=1&tid=1690262]: |
0ms |
get settings: |
7ms |
get forum list: |
14ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
52ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
48ms |
get tp. blocked users: |
1ms |
| others: | 236ms |
| total: | 376ms |

| 0 / 0 |
