|
|
|
оптимизация доступа к диску
|
|||
|---|---|---|---|
|
#18+
Имею вот такой план выполнения простого джойна двух таблиц. По индексу type_ts_cashier выбираются записи из таблицы pos_events, после чего эти записи по своему внешнему ключу соединяются с записями из таблицы pos_receipts. План получен "на холодную", сразу после загрузки СУБД и ОС. Код: sql 1. 2. 3. 4. 5. 6. 7. Вот в более читаемом виде: http://explain.depesz.com/s/Wyl Вопросы такие: 1. IndexScan'ы 500 записей занимают соответственно 800 и 1000 мс. С одной стороны, на примере второго IndexScan по pos_receipts_pkey, из плана видно, что это 500 seek по диску, каждый из которых занимает 2мс, что похоже на скорость доступа к диску. Но, с другой стороны, такое ощущение, что это очень медленно — целую секунду считывать 500 строк, и хочется как-то улучшить результат. Что можно для этого сделать? receipt_id — это идентификатор записи в таблице pos_receipts, случайный набор символов. На диске записи c receipt_id сейчас лежат в случайном порядке. 2. Что делает NestedLoop внутри себя в течение 1240 мс? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.03.2014, 15:56:34 |
|
||
|
оптимизация доступа к диску
|
|||
|---|---|---|---|
|
#18+
tdiffИмею вот такой план выполнения простого джойна двух таблиц. По индексу type_ts_cashier выбираются записи из таблицы pos_events, после чего эти записи по своему внешнему ключу соединяются с записями из таблицы pos_receipts. План получен "на холодную", сразу после загрузки СУБД и ОС. Код: sql 1. 2. 3. 4. 5. 6. 7. Вот в более читаемом виде: http://explain.depesz.com/s/Wyl Вопросы такие: 1. IndexScan'ы 500 записей занимают соответственно 800 и 1000 мс. С одной стороны, на примере второго IndexScan по pos_receipts_pkey, из плана видно, что это 500 seek по диску, каждый из которых занимает 2мс, что похоже на скорость доступа к диску. Но, с другой стороны, такое ощущение, что это очень медленно — целую секунду считывать 500 строк, и хочется как-то улучшить результат. Что можно для этого сделать? receipt_id — это идентификатор записи в таблице pos_receipts, случайный набор символов. На диске записи c receipt_id сейчас лежат в случайном порядке. 2. Что делает NestedLoop внутри себя в течение 1240 мс? 1)или поставить больше памяти чтобы база в основном была в оперативке (а тормоза при холодном старте базы они у всех и всегда) или вместо механики использовать нормальные серверные ssd (легко может в 100 раз быстрее быть) Больше особо ничего сделать нельзя... хотя... если индекс у вас сделан как (event_type, lower(name), ts) то поможет cluster первой таблицы по этому индексу... по 2 лучше всего наверное включить track_io_timing в базе и делать explain (analyze, costs, buffers, timing) там будет виднее что происходит. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.03.2014, 01:27:58 |
|
||
|
оптимизация доступа к диску
|
|||
|---|---|---|---|
|
#18+
Maxim Boguk1)или поставить больше памяти чтобы база в основном была в оперативке (а тормоза при холодном старте базы они у всех и всегда) или вместо механики использовать нормальные серверные ssd (легко может в 100 раз быстрее быть) Больше особо ничего сделать нельзя... хотя... если индекс у вас сделан как (event_type, lower(name), ts) то поможет cluster первой таблицы по этому индексу... по 2 лучше всего наверное включить track_io_timing в базе и делать explain (analyze, costs, buffers, timing) там будет виднее что происходит. спасибо, попробую ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.03.2014, 15:39:50 |
|
||
|
оптимизация доступа к диску
|
|||
|---|---|---|---|
|
#18+
tdiffMaxim Boguk1)или поставить больше памяти чтобы база в основном была в оперативке (а тормоза при холодном старте базы они у всех и всегда) или вместо механики использовать нормальные серверные ssd (легко может в 100 раз быстрее быть) Больше особо ничего сделать нельзя... хотя... если индекс у вас сделан как (event_type, lower(name), ts) то поможет cluster первой таблицы по этому индексу... по 2 лучше всего наверное включить track_io_timing в базе и делать explain (analyze, costs, buffers, timing) там будет виднее что происходит. спасибо, попробую хэш джоин попробуй. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.03.2014, 17:34:47 |
|
||
|
оптимизация доступа к диску
|
|||
|---|---|---|---|
|
#18+
а как форсиовать использование хэш джойна? set enable_nestloop = false? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.03.2014, 16:33:05 |
|
||
|
оптимизация доступа к диску
|
|||
|---|---|---|---|
|
#18+
tdiffа как форсиовать использование хэш джойна? set enable_nestloop = false? для начала статистику обнови ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.03.2014, 16:49:03 |
|
||
|
оптимизация доступа к диску
|
|||
|---|---|---|---|
|
#18+
Ivan Durak, это само собой default_statistics_target=1000 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.03.2014, 16:54:42 |
|
||
|
оптимизация доступа к диску
|
|||
|---|---|---|---|
|
#18+
tdiffIvan Durak, это само собой default_statistics_target=1000 кстати а где запрос? или хотябы условие соединения? там эквисоединение нормальное? типы одинаковые? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.03.2014, 17:03:12 |
|
||
|
оптимизация доступа к диску
|
|||
|---|---|---|---|
|
#18+
Ivan Durak, Схема такая: Код: sql 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. индекс type_ts_cashier — сделан специально под наиболее характерные запросы вида: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.03.2014, 17:06:47 |
|
||
|
оптимизация доступа к диску
|
|||
|---|---|---|---|
|
#18+
покажите пожалуйста select count(*) from pos_events where event_ts_received >= 1202118750621000 and event_ts_received <= 1393926750621000; select count(*) from pos_events where event_type = 300; select count(*) from pos_events where lower(event_cashier_name) = lower('Мартынович Виктория Николаевна'); и, может быть даже, то же кол-во строк по комбинациям этих трех ограничений. ограничение по event_type сформулировано с использованием IN, там могут оказаться несколько значений? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.03.2014, 17:44:09 |
|
||
|
оптимизация доступа к диску
|
|||
|---|---|---|---|
|
#18+
LeXa NalBatпокажите пожалуйста select count(*) from pos_events where event_ts_received >= 1202118750621000 and event_ts_received <= 1393926750621000; 3748388 select count(*) from pos_events where event_type = 300; 1830397, но event_type = 300 - самое часто встречающееся событие. например, для event_type=2000 всего найдётся 220869 записей, для event_type=314 - 1720 записей. На план запроса event_type не влияет. select count(*) from pos_events where lower(event_cashier_name) = lower('Мартынович Виктория Николаевна'); 106439 и, может быть даже, то же кол-во строк по комбинациям этих трех ограничений. 53850 ограничение по event_type сформулировано с использованием IN, там могут оказаться несколько значений? Да, в случае более общего запроса могут оказаться несколько event_type или event_cashier_name. Но требуется добиться максимальной скорости выполнения запроса именно такого вида, когда задан только один event_type и один event_cashier_name. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.03.2014, 17:54:20 |
|
||
|
оптимизация доступа к диску
|
|||
|---|---|---|---|
|
#18+
tdiff53850 Ну вот. Оптимизатор по статистике решил что выберется 500 записей, а выбралось на 2 порядка больше. 500 сиков по индексу возможно и быстрее скана и хэш джоина. А вот 53000 явно медленнее. Так что хинтуй хэш джоин ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.03.2014, 18:59:30 |
|
||
|
оптимизация доступа к диску
|
|||
|---|---|---|---|
|
#18+
блин, туплю!! у тебя же там лимит 500!! не поможет хэш, короче если у тебя рецепты есть для любого event - просто лимит 500 выбери до джоина! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.03.2014, 19:03:16 |
|
||
|
оптимизация доступа к диску
|
|||
|---|---|---|---|
|
#18+
Ivan Durak, Это да, limit. Выбирать в отдельную таблицу пробовал, не даёт эффекта. По-моему тут беда в том, что упираюсь в скорость диска. Совет использовать кластер по индексу не подходит, потому что в реальности есть ещё один часто встречающийся запрос, в котором вместо event_cashier_name фильтруется по event_terminal. Абсолютно аналогичный запрос, для которого есть точно такой же индекс (event_type, event_ts, event_terminal). А кластеризовать можно только по одному индексу. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.03.2014, 19:18:41 |
|
||
|
оптимизация доступа к диску
|
|||
|---|---|---|---|
|
#18+
tdiff, хазяина, ты порядку словов попутала вот так попробовай, однако Код: sql 1. 2. 3. 4. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.03.2014, 20:02:55 |
|
||
|
оптимизация доступа к диску
|
|||
|---|---|---|---|
|
#18+
йокарный бабайtdiff, хазяина, ты порядку словов попутала вот так попробовай, однако Код: sql 1. 2. 3. 4. Спасибо. Не повлияло на скорость, что ещё раз подтверждает идею о том, что упирается в ввод\вывод. Плюс так теряется возможность использовать этот индекс для поиска без фильтрации по event_cashier_name. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.03.2014, 20:45:31 |
|
||
|
оптимизация доступа к диску
|
|||
|---|---|---|---|
|
#18+
йокарный бабайtdiff, хазяина, ты порядку словов попутала вот так попробовай, однако Код: sql 1. 2. 3. 4. только не так а event_ts_received на первое место (event_ts_received, event_type , lower(event_cashier_name) COLLATE pg_catalog."default") дадим оптимизатору шанс не весь индекс сканить ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.03.2014, 07:27:44 |
|
||
|
оптимизация доступа к диску
|
|||
|---|---|---|---|
|
#18+
[quot tdiff]йокарный бабайtdiff, <> Спасибо. Не повлияло на скорость, что ещё раз подтверждает идею о том, что упирается в ввод\вывод. Плюс так теряется возможность использовать этот индекс для поиска без фильтрации по event_cashier_name.а план где ? если я правильно понял результат (и если вы не облажались) то у вас вдоль индекса утеряны записи в pos_receipts -- для INNER JOIN pos_receipts ON pos_events.event_receipt_id = pos_receipts.receipt_id. иначе это был бы максимум луп 500 записей вдоль индекса. А это всяко быстрее 3000, если только индекс у вас не полон дед-роусов (а он - свежий). и ещё - это по "горячему" или по "холодному" ? т.е. индексы уже в памяти, или ещё нет? да, а часом в записях у вас не блобы мегабайтные ? тогда откусите их в списке вывода из *, и повторите без них. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.03.2014, 08:30:14 |
|
||
|
оптимизация доступа к диску
|
|||
|---|---|---|---|
|
#18+
[quot йокарный бабай]tdiffпропущено... а план где ? если я правильно понял результат (и если вы не облажались) то у вас вдоль индекса утеряны записи в pos_receipts -- для INNER JOIN pos_receipts ON pos_events.event_receipt_id = pos_receipts.receipt_id. иначе это был бы максимум луп 500 записей вдоль индекса. А это всяко быстрее 3000, если только индекс у вас не полон дед-роусов (а он - свежий). и ещё - это по "горячему" или по "холодному" ? т.е. индексы уже в памяти, или ещё нет? да, а часом в записях у вас не блобы мегабайтные ? тогда откусите их в списке вывода из *, и повторите без них. насколько я понимаю вопрос о скорости работы на холодную был в начале... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.03.2014, 11:57:12 |
|
||
|
оптимизация доступа к диску
|
|||
|---|---|---|---|
|
#18+
[quot Maxim Boguk]йокарный бабайпропущено... насколько я понимаю вопрос о скорости работы на холодную был в начале...500*(2+N[toast]) произвольных доступов -- только на чтение записей. По ~60/(10 000) sec/доступ - те самые 3000[+-] и набегают. Временем поднятия страницы-другой индекса можно и пренебречь. Т.е. или в память побольше поднимать заранее, для чего её иметь (или SSD ?) , или думать на предмет кластеризованных (по разному) "мат-вью"[ но это жуткий чемодан без ручки, работающий к тому же только если не часто апдейтится набор, но утяжеляющий базу в разы] поэтому проще смириться ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.03.2014, 12:17:26 |
|
||
|
оптимизация доступа к диску
|
|||
|---|---|---|---|
|
#18+
tdiffНе повлияло на скорость...покажите explain (analyze, buffers) select ... при наличии индекса по (event_type , lower(event_cashier_name), event_ts_received) tdiffПлюс так теряется возможность использовать этот индекс для поиска без фильтрации по event_cashier_name.да, для поиска без ограничения по event_cashier_name нужно наличие еще одного, другого индекса ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2014, 09:54:05 |
|
||
|
|

start [/forum/topic.php?fid=53&fpage=131&tid=1998796]: |
0ms |
get settings: |
8ms |
get forum list: |
14ms |
check forum access: |
7ms |
check topic access: |
7ms |
track hit: |
289ms |
get topic data: |
14ms |
get forum data: |
4ms |
get page messages: |
114ms |
get tp. blocked users: |
2ms |
| others: | 216ms |
| total: | 675ms |

| 0 / 0 |
