|
|
|
Создание оптимальных индексов
|
|||
|---|---|---|---|
|
#18+
Есть вопрос по оптимизации. Как создать индекс для конкретного запроса? Коков алгоритм действий, куда смотреть? Informix Dynamic Server 2000 Version 9.21.HC3 стоит под вебом http://www.micex.ru/online/stock/archive/ Типичный запрос Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. то что находится между комментариями "-- мигает" - иногда присутствует в запросе, иногда - нет. Я делал так - создавал все кучу индексов на ngcb_hist по всем полям, участвующем в запросе (всевозможные перестановки id, trdate, boardGroup, numtrades), делал апдейт статистикс хай, запускал запрос с експлайном и смотрел какие индексы использует информикс. Оставались несколько индексов, их-то и переносил в боевую БД. Понимаю, что шел экстенсивным путем, но интенсивного ниасилил. Все эти рассуждения о селективности не смог применить в реальной ситуации - как не делаю, информикс не хочет использовать мои индексы :( Чего-то я недопонимаю... Может многоуважаемое сообщество подскажет _правильный_ путь создания оптимальных индексов для конкретных запросов? Кто как делает? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.11.2005, 16:35 |
|
||
|
Создание оптимальных индексов
|
|||
|---|---|---|---|
|
#18+
Сугубый... Код: plaintext 1. мало информации (сколько строк возратится без FIRST 20), планы хотя-бы. дурацкое предположение: SELECT /*+ first_rows*/ FIRST 20 h.pos, h.id, h.idBoard, TO_CHAR(h.trdate, '%Y-%m-%d'), и индекс по h.pos ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.11.2005, 17:01 |
|
||
|
Создание оптимальных индексов
|
|||
|---|---|---|---|
|
#18+
Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. без FIRST запрос вернет порядка 1000 записей. Видно что в данном случае планировщик использовал индекс (trdate, id, boardgroup, numtrades) Я не про этот конкретный запрос. У меня таких штук 20, на разных таблицах, с разным соотношением distinct id, distinct boardgroup, distinct numtrades... Какой _правильный_ алгоритм построения оптимального индекса? На что обращать внимание, как определять порядок колонок в индексе? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.11.2005, 17:31 |
|
||
|
Создание оптимальных индексов
|
|||
|---|---|---|---|
|
#18+
Журавлев Денис и индекс по h.pos это для order by? по моему он будет бесполезен при связывании нескольких таблиц. ведь отфильрованный резалт сет пишется в tmpdb, а толко потом упорядочивается. вот если б одна табличка была... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.11.2005, 18:16 |
|
||
|
Создание оптимальных индексов
|
|||
|---|---|---|---|
|
#18+
Сугубый Журавлев Денис и индекс по h.pos это для order by? по моему он будет бесполезен при связывании нескольких таблиц. ведь отфильрованный резалт сет пишется в tmpdb, а толко потом упорядочивается. вот если б одна табличка была... :) SELECT /*+ first_rows*/ FIRST 20 h.pos, h.id, h.idBoard, TO_CHAR(h.trdate, '%Y-%m-%d'), ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.11.2005, 20:56 |
|
||
|
Создание оптимальных индексов
|
|||
|---|---|---|---|
|
#18+
Сугубый без FIRST запрос вернет порядка 1000 записей. Видно что в данном случае планировщик использовал индекс (trdate, id, boardgroup, numtrades) Судя по Filters: (denn.h.publ = 2 AND denn.h.pos >= 6543 ) более эффективным был бы trdate, pos. Сугубыйh.id IN (SELECT id FROM secsLI WHERE idSecList='INDEXSECS' AND idSector='securies' AND sec_publ=1)Видимо информикс думает что SELECT id FROM secsLI вернет много строк, кстати у меня есть подозрение в этом случае лучше не IN, а EXSIST, и вообще переделать подзапрос в джойн, если он возвращает более одной строки. СугубыйЯ не про этот конкретный запрос. У меня таких штук 20, на разных таблицах, с разным соотношением distinct id, distinct boardgroup, distinct numtrades... Возможно надо несколько индексов, надо цель оптимизации сначала определить, а потом ставить задачи. СугубыйКакой _правильный_ алгоритм построения оптимального индекса? На что обращать внимание, как определять порядок колонок в индексе?Оптимальных индексов не бывает, нужен критерий оптимальности. Самое важное это правильный порядок соединения таблиц, индексы на втором месте. Про порядок колонок: индекс может использоваться если его первые поля были в запросе. в запросе where trdate =? может использоваться индекс (trdate, id) а (id, trdate) не может но (id, trdate) может использоваться при where trdate = ? and id =? Если id внешний ключ, то возможно нужен индекс где оно первое. Если h.numtrades>0 редко (отсекаем выходные?), то его можно не включать в индексы. Если во многих запросах есть h.pos>=? AND h.publ=? AND h.trdate=?, то возможно нужен trdate, publ, pos, но все зависит от селективности. Например если publ всегда =2, то в индекс его можно не включать. Но если селективность высокая или есть исключения, то его можно включить. Бд на мой вкус криво спроектирована: FROM secs s WHERE s.idSector='securies' FROM secsLI WHERE idSector='securies' FROM boardSelect WHERE idSector='securies' ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.11.2005, 09:38 |
|
||
|
Создание оптимальных индексов
|
|||
|---|---|---|---|
|
#18+
Журавлев Денис :) SELECT /*+ first_rows*/ FIRST 20 h.pos, h.id, h.idBoard, TO_CHAR(h.trdate, '%Y-%m-%d'), ой, а как такие большие буквы сделать? ;))) Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. Разницы в планах выполнения я не заметил. И забил на директивы оптимизатора... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.11.2005, 13:58 |
|
||
|
Создание оптимальных индексов
|
|||
|---|---|---|---|
|
#18+
Журавлев Денис Бд на мой вкус криво спроектирована: FROM secs s WHERE s.idSector='securies' FROM secsLI WHERE idSector='securies' FROM boardSelect WHERE idSector='securies' Ага - особенно если idSector [N]VARCHAR :) Смотри прочие thread'ы про индексы :)) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.11.2005, 14:02 |
|
||
|
Создание оптимальных индексов
|
|||
|---|---|---|---|
|
#18+
Сугубый Разницы в планах выполнения я не заметил. И забил на директивы оптимизатора... А сколько времени запрос выполняется? А без order by сколько? На самом деле first_rows хороший хинт, и информикс не будет сортировать, а пойдет по индексу, даже если джойнится много таблиц. Это даже не хинт, это доп.информация оптимизатору, что нам нужны первые строки, ведь у вас first 20 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.11.2005, 14:04 |
|
||
|
Создание оптимальных индексов
|
|||
|---|---|---|---|
|
#18+
АнатоЛой Журавлев Денис Бд на мой вкус криво спроектирована: FROM secs s WHERE s.idSector='securies' FROM secsLI WHERE idSector='securies' FROM boardSelect WHERE idSector='securies' Ага - особенно если idSector [N]VARCHAR :) Смотри прочие thread'ы про индексы :)) Индекс тут как раз используется, проблемы с VARCHAR остались в прошлом, в 7-ке. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.11.2005, 14:07 |
|
||
|
Создание оптимальных индексов
|
|||
|---|---|---|---|
|
#18+
Денис, не могли бы вы определить понятие селективности? А то никто мне внятно не может обьяснить. Спасибо заранее :) Журавлев ДенисСудя по Filters: (denn.h.publ = 2 AND denn.h.pos >= 6543 ) более эффективным был бы trdate, pos. Эффективность индекса как раз и определяется этой селективностью, как я понял. Если первый ключ может существенно сузить облать поиска, то выбирается именно он. trdate - это дата, данные хранятся за несколько лет, за один день порядка 400 записей. Роs - уникальна для каждой строки (не спрашивайте почему) Насколько селективен индекс по trdate? Журавлев ДенисВидимо информикс думает что SELECT id FROM secsLI вернет много строк, кстати у меня есть подозрение в этом случае лучше не IN, а EXSIST, и вообще переделать подзапрос в джойн, если он возвращает более одной строки. Джойн мне немного сложнее формировать... Впрочем, где-то прочитал что подселекты оптимизатор все равно раскладывает в джойн. Журавлев Денис Возможно надо несколько индексов, надо цель оптимизации сначала определить, а потом ставить задачи. Цель оптимизации - скорострельность. Параметр - чем больше тем лучше. Текущий уровень, в принципе, удовлетворяет, но потолок уже близок... Другая цель оптимизации - научится оптимизации :) Журавлев Денис Оптимальных индексов не бывает, нужен критерий оптимальности. Самое важное это правильный порядок соединения таблиц, индексы на втором месте. Про порядок колонок: индекс может использоваться если его первые поля были в запросе. в запросе where trdate =? может использоваться индекс (trdate, id) а (id, trdate) не может но (id, trdate) может использоваться при where trdate = ? and id =? Если id внешний ключ, то возможно нужен индекс где оно первое. Если h.numtrades>0 редко (отсекаем выходные?), то его можно не включать в индексы. Если во многих запросах есть h.pos>=? AND h.publ=? AND h.trdate=?, то возможно нужен trdate, publ, pos, но все зависит от селективности. Например если publ всегда =2, то в индекс его можно не включать. Но если селективность высокая или есть исключения, то его можно включить. Бд на мой вкус криво спроектирована: FROM secs s WHERE s.idSector='securies' FROM secsLI WHERE idSector='securies' FROM boardSelect WHERE idSector='securies' h.numtrades>0 у 2/3 записей publ=2 практически всегда (99,9% строк) Вкусы на структуру БД у всех разные ;) Насчет порядка соединения - а как бы его проанализировать? Есть 3 таблицы, одна так сказать ведущая, 2 - вспомогательные; вспомогательные вяжутся в главной одним полем; на все таблички наклыдываются разнообразные условия. И еще раз - что же такое селективность?... (где же у него кнопка? (ц) Урри :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.11.2005, 14:16 |
|
||
|
Создание оптимальных индексов
|
|||
|---|---|---|---|
|
#18+
Журавлев ДенисИндекс тут как раз используется, проблемы с VARCHAR остались в прошлом, в 7-ке. ОК, уболтали :) В ближайшее время возвращаюсь из прошлого... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.11.2005, 14:21 |
|
||
|
Создание оптимальных индексов
|
|||
|---|---|---|---|
|
#18+
Журавлев Денис Сугубый Разницы в планах выполнения я не заметил. И забил на директивы оптимизатора... А сколько времени запрос выполняется? А без order by сколько? На самом деле first_rows хороший хинт, и информикс не будет сортировать, а пойдет по индексу, даже если джойнится много таблиц. Это даже не хинт, это доп.информация оптимизатору, что нам нужны первые строки, ведь у вас first 20 времена не тестировал :( каюсь. Слишком много запросов, надо было бить по площадям. Сейчас - можно и потестировать (кста, как в dbaccess выводить время выпалнения - есть така фича?) А оптимизатор сам что ли не видит, что у него в запросе first 20? %) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.11.2005, 14:23 |
|
||
|
Создание оптимальных индексов
|
|||
|---|---|---|---|
|
#18+
СугубыйДенис, не могли бы вы определить понятие селективности? А то никто мне внятно не может обьяснить. Спасибо заранее :)Ох, тяжело это. Давай, не будем говорить большая и маленькая селективность, а то совсем запутаемся, будем говорить хорошая селективность. Поле F содержит много разных значений 0,1,2,3,2,1,4 выполняется много запросов where F=? - селективность поля хорошая. Поле F содержит мало разных значений 0,0,0,0,0,0,1,1,1,1 селективность поля плохая. Поле F содержит мало разных значений 0,0,0,0,0,0,0,4 выполняется много запросов where F=0 - селективность поля плохая, а для where F=4 - селективность поля хорошая. СугубыйНасчет порядка соединения - а как бы его проанализировать? Есть 3 таблицы, одна так сказать ведущая, 2 - вспомогательные; вспомогательные вяжутся в главной одним полем; на все таблички наклыдываются разнообразные условия. Читаем план: Код: plaintext 1. 2. 3. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.11.2005, 14:32 |
|
||
|
Создание оптимальных индексов
|
|||
|---|---|---|---|
|
#18+
Сугубый выбирается именно он. trdate - это дата, данные хранятся за несколько лет, за один день порядка 400 записей. Роs - уникальна для каждой строки (не спрашивайте почему) Насколько селективен индекс по trdate? Индекс по trdate эффективен, по Роs намного эффективнее при условии что Роs используется в where. Сугубый Цель оптимизации - скорострельность. Параметр - чем больше тем лучше. Текущий уровень, в принципе, удовлетворяет, но потолок уже близок... Другая цель оптимизации - научится оптимизации :) Я понял сейчас. Вы этим запросом листаете 1000 строк кусочками по 20 строк с помощью Роs >, вам однозначно надо уйти от сортировки. Сугубыйh.numtrades>0 у 2/3 записей Плохая селективность. Индекс не нужен. Сугубый publ=2 практически всегда (99,9% строк)Очень плохая селективность. Индекс не нужен. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.11.2005, 14:42 |
|
||
|
Создание оптимальных индексов
|
|||
|---|---|---|---|
|
#18+
Сугубыйвремена не тестировал :( каюсь. Слишком много запросов, надо было бить по площадям.Как можно оптимизировать "скорострельность" без времени? Сугубый Сейчас - можно и потестировать (кста, как в dbaccess выводить время выпалнения - есть така фича?)Не знаю как dbaccess :(. Чаще пользуюсь eSQLEditor , там вроде есть такая фича. Сугубый А оптимизатор сам что ли не видит, что у него в запросе first 20? %)По моему не видит, 100% гарантии дать не могу. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.11.2005, 14:47 |
|
||
|
Создание оптимальных индексов
|
|||
|---|---|---|---|
|
#18+
Журавлев ДенисИндекс по trdate эффективен, по Роs намного эффективнее при условии что Роs используется в where. сначала я создавал такие составные индексы, в которых pos был на первом месте. оптимизатор их _не_использовал_ , наверно потому что у меня стоит pos > NNN и индекс по этому полю отсекает половину таблицы. А это мало. Оптимизатору лучше сразу выкусить из всех значений наименьший кусок. И он ставил на первые места trdate (дату, одну из нескольких лет) Журавлев Денис Я понял сейчас. Вы этим запросом листаете 1000 строк кусочками по 20 строк с помощью Роs >, вам однозначно надо уйти от сортировки. Вот здесь поподробнее, плз. Я знаю, что индекс используется при сортировке, если только все выбираемые поля лежат в индексе. У меня же в ngcb_hist 30 полей. Все их в индекс? нереально. Журавлев Денис Сугубыйh.numtrades>0 у 2/3 записей Плохая селективность. Индекс не нужен. Сугубый publ=2 практически всегда (99,9% строк)Очень плохая селективность. Индекс не нужен. что и было выявлено на первых этапах, когда я просто создал по индексу на каждую колонку из where - оптимизатор их не использовал вообще Журавлев ДенисКак можно оптимизировать "скорострельность" без времени? на глазок :) по времени отклика браузера :) Журавлев Денис Не знаю как dbaccess :(. Чаще пользуюсь eSQLEditor , там вроде есть такая фича. пасиб, посмотрим. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.11.2005, 15:39 |
|
||
|
Создание оптимальных индексов
|
|||
|---|---|---|---|
|
#18+
Сугубый Журавлев Денис Я понял сейчас. Вы этим запросом листаете 1000 строк кусочками по 20 строк с помощью Роs >, вам однозначно надо уйти от сортировки. Вот здесь поподробнее, плз. Я знаю, что индекс используется при сортировке, если только все выбираемые поля лежат в индексе. У меня же в ngcb_hist 30 полей. Все их в индекс? нереально. Вы путаете, в индексе должны быть поля по которым сортируется. Сделай индекс (trdate, pos), собери статистику, и покажите план: Код: plaintext 1. 2. 3. 4. 5. А зачем надо 30 полей сразу? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.11.2005, 15:58 |
|
||
|
Создание оптимальных индексов
|
|||
|---|---|---|---|
|
#18+
Журавлев Денис Сугубый Сейчас - можно и потестировать (кста, как в dbaccess выводить время выпалнения - есть така фича?)Не знаю как dbaccess :(. Чаще пользуюсь eSQLEditor , там вроде есть такая фича. Сугубый А оптимизатор сам что ли не видит, что у него в запросе first 20? %)По моему не видит, 100% гарантии дать не могу. А прикольная у вас программка :) Пасиба, буду юзать. Скорость выполнения с {+First} и без него одинаковы (в пределах точности) - 250 и 280 миллисек, к примеру. Видать оптимизатор сам видит, что у него FIRST 20 в запросе стоит :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.11.2005, 15:59 |
|
||
|
Создание оптимальных индексов
|
|||
|---|---|---|---|
|
#18+
СугубыйСкорость выполнения с {+First} и без него одинаковы (в пределах точности) - 250 и 280 миллисек, к примеру. Видать оптимизатор сам видит, что у него FIRST 20 в запросе стоит :)Это ничего не доказывает. Я не поверю, пока не увижу что из-за FIRST 20 меняется план. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.11.2005, 16:02 |
|
||
|
Создание оптимальных индексов
|
|||
|---|---|---|---|
|
#18+
ой, ошибся, с /*+first_rows*/ - то же саме. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.11.2005, 16:08 |
|
||
|
Создание оптимальных индексов
|
|||
|---|---|---|---|
|
#18+
Сугубыйой, ошибся, с /*+first_rows*/ - то же саме.Да я догадался. Просто смотрим первую строку плана при first_rows и видим: Код: plaintext А без хинта, один first 20: Код: plaintext ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.11.2005, 16:12 |
|
||
|
Создание оптимальных индексов
|
|||
|---|---|---|---|
|
#18+
Журавлев ДенисВы путаете, в индексе должны быть поля по которым сортируется. Сделай индекс (trdate, pos), собери статистику, и покажите план: Код: plaintext 1. 2. 3. 4. 5. Сделал и вот что получилось: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. он его не использует вообще. Ему больше нравится (trdate boardgroup id numtrades) счас делаю update statistics HIGH для ngcb_hist - может что поменяется Журавлев Денис А зачем надо 30 полей сразу? ну вот к примеру http://www.micex.ru/online/stock/archive/by_date.html?ssector=securies&doSearch=auto ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.11.2005, 16:18 |
|
||
|
Создание оптимальных индексов
|
|||
|---|---|---|---|
|
#18+
Попробуй: SELECT /*+first_rows*/ FIRST 20 h.trdate, h.pos, .... ... ORDER BY 1, 2 Сугубый счас делаю update statistics HIGH для ngcb_hist - может что поменяется HIGH необязательно, в случае добавления нового индекса. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.11.2005, 16:32 |
|
||
|
Создание оптимальных индексов
|
|||
|---|---|---|---|
|
#18+
упс, накладочка, перепутал сервера где выполнялись запросы :( Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. индекс испорльзуется и пропала строчка Temporary Files Required For: Order By - значит сортировка идет по индексу? Интересно ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.11.2005, 16:38 |
|
||
|
|

start [/forum/topic.php?fid=44&msg=33406632&tid=1608822]: |
0ms |
get settings: |
8ms |
get forum list: |
15ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
37ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
66ms |
get tp. blocked users: |
1ms |
| others: | 195ms |
| total: | 338ms |

| 0 / 0 |
