|
|
|
Медленный SELECT по индексам
|
|||
|---|---|---|---|
|
#18+
Добрый день! Не могу понять, в чем проблема. Есть вот такой запрос на таблице в 25 млн. строк. Код: plsql 1. Его EXPLAIN показывает следующее: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. Понятно, что он шарится по диску (shared_buffers установлены в 8 Гбайт), поскольку фактически перебирает всю таблицу целиком. Но почему он перебирает все записи на индексированной таблице? Как можно оптимизировать подобный запрос? Заранее спасибо ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2014, 09:06:56 |
|
||
|
Медленный SELECT по индексам
|
|||
|---|---|---|---|
|
#18+
Stan_1, Может быть подойдет такой запрос: Код: sql 1. 2. 3. 4. 5. Так же попробуйте составной индекс: Код: sql 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2014, 09:14:14 |
|
||
|
Медленный SELECT по индексам
|
|||
|---|---|---|---|
|
#18+
Я не уверен насчет Postgre,но у вас is_processed принимает только 2 значения. Если is_processed=false > 20% строк,то индекс по этому полю не имеет смысла, в итоге будет перебор всех записей. Проще ввести суррогатное вычисляемое поле с индексом, либо индекс по функции где уникальных значений было бы больше , либо маркер записей,который в ходят в первые 500(как вариант материализованная view), тогда индекс отлично будет работать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2014, 10:38:25 |
|
||
|
Медленный SELECT по индексам
|
|||
|---|---|---|---|
|
#18+
Stan_1Добрый день! Не могу понять, в чем проблема. Есть вот такой запрос на таблице в 25 млн. строк. Код: plsql 1. Его EXPLAIN показывает следующее: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. Понятно, что он шарится по диску (shared_buffers установлены в 8 Гбайт), поскольку фактически перебирает всю таблицу целиком. Но почему он перебирает все записи на индексированной таблице? Как можно оптимизировать подобный запрос? Заранее спасибо Есть шустрый но не гарантированный вариант: SELECT myid FROM ( SELECT myid,is_processed FROM big_table LIMIT 50000 (--ставь число строк в которе попадет 500 уникальных) ) sub WHERE is_processed=false GROUP BY myid LIMIT 500; Тут будет скан только 50к строк из индекса что на порядки меньше всей таблицы ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2014, 12:40:02 |
|
||
|
Медленный SELECT по индексам
|
|||
|---|---|---|---|
|
#18+
или даже так SELECT myid FROM ( SELECT myid,is_processed FROM big_table WHERE is_processed=false LIMIT 50000 (--ставь число строк в которе попадет 500 уникальных) ) sub GROUP BY myid LIMIT 500; ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2014, 12:42:08 |
|
||
|
Медленный SELECT по индексам
|
|||
|---|---|---|---|
|
#18+
классика. см тут: http://www.sql.ru/forum/882778/bystryy-podschet-distinct-values-po-indeksirovannym-polyam?hl=distinct ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2014, 14:36:40 |
|
||
|
Медленный SELECT по индексам
|
|||
|---|---|---|---|
|
#18+
/\/\/\/\/\/\Stan_1, Может быть подойдет такой запрос: Код: sql 1. 2. 3. 4. 5. Нет, ситуация такая же. Но здесь прав Troglodit в письме ниже (и причина на поверхности). Если индекс на 80% состоит из одного значения, то Index Scan практически превращается в Seq Scan /\/\/\/\/\/\Stan_1, Так же попробуйте составной индекс: Код: sql 1. А это я обязательно попробую, и потом отпишусь. Самому интересно стало. :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2014, 15:38:47 |
|
||
|
Медленный SELECT по индексам
|
|||
|---|---|---|---|
|
#18+
Stan_1, имеет смысл попробовать создать такой индекс: Код: sql 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2014, 15:44:52 |
|
||
|
Медленный SELECT по индексам
|
|||
|---|---|---|---|
|
#18+
Ну все, вроде сделал следующим образом. Ввел столбец shard_id, и сделал составной индекс: shard_id, is_processed. Затем дал каждой 300 тыс. записей свое значение shard_id. И все стало работать быстро. Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2014, 21:40:38 |
|
||
|
|

start [/forum/topic.php?fid=53&gotonew=1&tid=1998503]: |
0ms |
get settings: |
9ms |
get forum list: |
15ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
428ms |
get topic data: |
8ms |
get first new msg: |
5ms |
get forum data: |
2ms |
get page messages: |
33ms |
get tp. blocked users: |
1ms |
| others: | 228ms |
| total: | 735ms |

| 0 / 0 |
