|
|
|
Filter cost в Index Scan
|
|||
|---|---|---|---|
|
#18+
Есть большая таблица ( >3млн записей). Там выполняется примитивный запрос: Код: sql 1. 2. 3. 4. 5. 6. 7. По сути берется временная таблица и в большой таблице отбираются все записи с 4 полями из этой временной таблицы. В таблице есть несколько индексов. В частности по всем 4 полям, но есть по 2 и 3-м (price+date например). При выполнении postgres почему-то выбирает индекс с наименьшим числом полей и получает такой план: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. Если убрать этот индекс, он начинает использовать индекс по 3, и только когда никакого другого индекса нет, начинает использовать индекс по 4 и получает следующий план: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. Проблема с использованием индекса усугубляется, когда shared_buffers'ов не хватает и план становится таким: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. (то есть еще переполняется shared_buffers, что совсем не айс). Причем плохой план она выбирает, потому что cost чуть-чуть меньше. По идее на него должен влиять effective_cache_size, но он ни на что не влияет (если его поставить даже 20МБ план остается) Также при изменении page_cost, tuple_cost, cost'ы увеличиваются: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. Но при этом этот план все равно приоритетнее. Причем на другом компе с такой же версией БД и теми же настройками она выбирает правильный план (но на большинстве все же не правильный). Вопрос что влияет на определения cost'а при Filter в Index Scan. Почему он такой маленький и что на него еще может влиять? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.04.2016, 12:22 |
|
||
|
Filter cost в Index Scan
|
|||
|---|---|---|---|
|
#18+
Хотя видимо понятна причина, она не видит корреляцию между sku и price (товаром и его ценой) Соответственно если взглянуть на pg_stats Колонки: "receiptskuledger_receiptsaleskuledger";"key0" "receiptskuledger_receiptsaleskuledger";"receiptskuledger_date_receiptsaleskuledger" "receiptskuledger_receiptsaleskuledger";"receiptskuledger_price_receiptsaleskuledger" "receiptskuledger_receiptsaleskuledger";"receiptskuledger_departmentstore_receiptsaleskuledger" "receiptskuledger_receiptsaleskuledger";"receiptskuledger_sku_receiptsaleskuledger" "t_65";"k0" "t_65";"k1" "t_65";"k2" "t_65";"k3" n_distinct: -1 461 1414 43 13837 -0.99 -0.666667 -0.533333 -0.13 Она берет price * sku и считает selectivity очень большой и поэтому использует более короткий индекс. Вопрос как с этим можно бороться :( Кроме переконфигурации индексов чтобы не ставить коррелированные колонки рядом ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.04.2016, 12:57 |
|
||
|
Filter cost в Index Scan
|
|||
|---|---|---|---|
|
#18+
Nitro_Junkie, Цена узла строится из: - цены доступа к блокам, причём не важно, холодным или горячим - цены доступа к записи - цены каждой операции Цена доступа к блоку самая большая, поэтому “в среднем” база будет “предпочитать” индексы поменьше. Играть параметрами смысла нет, т.к. везде IndexScan, а он базируется на `random_page_cost` для блоков, т.е. цена будет меняться одинаково для всех вариантов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.04.2016, 14:09 |
|
||
|
Filter cost в Index Scan
|
|||
|---|---|---|---|
|
#18+
поспешил... В плане с IOS, присутствуют HeapFetches — планировщик их не любит. Что-то поменяется, если сделать `VACUUM ANALYZE` таблице перед запросом? И да — было бы интересно глянуть на определения объектов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.04.2016, 14:13 |
|
||
|
Filter cost в Index Scan
|
|||
|---|---|---|---|
|
#18+
vyegorovпоспешил... В плане с IOS, присутствуют HeapFetches — планировщик их не любит. Что-то поменяется, если сделать `VACUUM ANALYZE` таблице перед запросом? И да — было бы интересно глянуть на определения объектов. Хм... Вообще базовая проблема с неправильным Index selectivity (планировщик думает что sku+price отберет одну запись, но это не так из-за их корреляции), но действительно, непонятно почему не смотря на это планировщик не предпочитает использовать Index only scan вместо просто Index scan. Сейчас сделал VACUUM ANALYZE и везде план стал нормальным. Но непонятно почему. На всех базах по этой таблице делается VACUUM FULL раз в неделю, при приросте всего на 2-3% за этот период. Этого получается недостаточно? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.04.2016, 14:38 |
|
||
|
Filter cost в Index Scan
|
|||
|---|---|---|---|
|
#18+
Вот план новый (тут default'ые *_cost, поэтому сравнивать его имеет смысл с последним планом) Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.04.2016, 14:43 |
|
||
|
Filter cost в Index Scan
|
|||
|---|---|---|---|
|
#18+
Nitro_JunkieСейчас сделал VACUUM ANALYZE и везде план стал нормальным. Но непонятно почему. На всех базах по этой таблице делается VACUUM FULL раз в неделю, при приросте всего на 2-3% за этот период. Этого получается недостаточно? Недостаточно. Помимо прироста бывают ещё и измения. Для большой таблицы 2% прироста легко проскакивают порог, после которого планировщик считает таблицу "слишком грязной" и игнорирует IOS. VACUUM FULL делать часто не надо, это специальная команда которая перестраивает таблицу и индексы. Она думана для случаев, когда совсем всё плохо. Настройте autovacuum агрессивно, я делаю так: параметрзначениеautovacuum_analyze_scale_factor0.02autovacuum_vacuum_scale_factor0.005autovacuum_vacuum_cost_delay-1autovacuum_vacuum_cost_limit-1autovacuum_max_workers35 (не меньше 10)autovacuum_work_mem256MBlog_autovacuum_min_duration1000vacuum_cost_delay0vacuum_freeze_min_age10000000 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.04.2016, 16:52 |
|
||
|
|

start [/forum/topic.php?fid=53&fpage=93&tid=1997279]: |
0ms |
get settings: |
5ms |
get forum list: |
8ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
42ms |
get topic data: |
7ms |
get forum data: |
2ms |
get page messages: |
33ms |
get tp. blocked users: |
1ms |
| others: | 199ms |
| total: | 301ms |

| 0 / 0 |
