|
Explain and Indexes
|
|||
---|---|---|---|
#18+
# explain select * from emails where category_id > 2; QUERY PLAN ------------------------------------------------------------ Seq Scan on emails (cost=0.00..22.50 rows=333 width=154) Filter: (category_id > 2) (записей: 2) # explain select * from emails where category_id = 2; QUERY PLAN ------------------------------------------------------------------------------ Index Scan using emailsndx1 on emails (cost=0.00..17.07 rows=5 width=154) Index Cond: (category_id = 2) (записей: 2) Если я правильно понимаю эту информацию, то при условии 'category_id = 2' используется индекс, а при условии 'cetegory_id > 2' - нет (т.е. осуществляется полный перебор) Почему так происходит? Индекс же есть! ... |
|||
:
Нравится:
Не нравится:
|
|||
12.04.2004, 12:22 |
|
Explain and Indexes
|
|||
---|---|---|---|
#18+
Попробуйте сделать vacuum analyze emails. "(записей: 2)" - Это обозначает что в таблице две строки с category_id > 2, и две - с category_id = 2? ... |
|||
:
Нравится:
Не нравится:
|
|||
12.04.2004, 12:50 |
|
Explain and Indexes
|
|||
---|---|---|---|
#18+
автор"(записей: 2)" - Это обозначает что в таблице две строки с category_id > 2, и две - с category_id = 2? Нет - записей в таблице 1.000.000. Я её только что создал и не удалял и не редактировал, так что vacuum тут не причём ... |
|||
:
Нравится:
Не нравится:
|
|||
12.04.2004, 13:02 |
|
Explain and Indexes
|
|||
---|---|---|---|
#18+
А вообще какой тип индексов лучше использовать для внешних ключей? Я читал что индексы btree лучше использовать для числовых полей и полей типа дата/время. А hash - для текстовых полей. Также пишут что btree лучше подходит для операций <, > и сортировки, а hash - для = и <>. Внешний ключ - число, применяется операция сравнения. Что выбрать? Таблица будет иметь несколько миллионов записей. И ещё несколько наболевших вопросов: 1) Правда ли что unique индексы быстрее, чем простые индексы? 2) При таких объёмах стоит ли индексировать поле типа boolen (имеется/отсутствует)? Может оно без индекса быстрее будет? 3) Стоит ли индексировать поле типа varchar(255) - наименование. По нему будет производится поиск с помощью оператора like (скорее всего на плное вхождение: '%template%')? Eсли стоит, то каким индексом? Hash? Очень нужна помощь в этом вопросе! Буду длагодарен любым советам. ... |
|||
:
Нравится:
Не нравится:
|
|||
12.04.2004, 13:25 |
|
Explain and Indexes
|
|||
---|---|---|---|
#18+
"Я её только что создал и не удалял и не редактировал, так что vacuum тут не причём" Повторюсь: попробуйте сделать vacuum analyze emails. С ключом analyze постгрес собирает статистику, кроме выполнения действий с удаленными/измененными строками. Если это не поможет, то приведите пожалуйста результат работы двух ваших explain запросов с ключом analyze: explain analyze select * from emails where category_id > 2; explain analyze select * from emails where category_id = 2; ... |
|||
:
Нравится:
Не нравится:
|
|||
12.04.2004, 13:26 |
|
Explain and Indexes
|
|||
---|---|---|---|
#18+
авторТаблица будет иметь несколько миллионов записей. Уточнение: даже несколько десятков миллионов (от 10.000.000 до 100.000.000) ... |
|||
:
Нравится:
Не нравится:
|
|||
12.04.2004, 13:27 |
|
Explain and Indexes
|
|||
---|---|---|---|
#18+
авторЕсли это не поможет, то приведите пожалуйста результат работы двух ваших explain запросов с ключом analyze: explain analyze select * from emails where category_id > 2; explain analyze select * from emails where category_id = 2; # explain analyze select * from emails where category_id = 2; QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------- Index Scan using emailsndx1 on emails (cost=0.00..17.07 rows=5 width=154) (actual time=180.16..41126.74 rows=10130 loops=1) Index Cond: (category_id = 2) Total runtime: 41150.82 msec (записей: 3) # explain analyze select * from emails where category_id > 2; QUERY PLAN ------------------------------------------------------------------------------------------------------------- Seq Scan on emails (cost=0.00..22.50 rows=333 width=154) (actual time=28.41..6218.24 rows=979922 loops=1) Filter: (category_id > 2) Total runtime: 6955.11 msec (записей: 3) Вот такие результаты. Вопрос: analyze собирает статистику для последующей оптимизации. Это значит что analyze нужно делать для всех запросов: analyze select * from emails where category_id = 1; analyze select * from emails where category_id = 2; ........ analyze select * from emails where category_id > 1; analyze select * from emails where category_id > 2; .......... или достаточно analyze select * from emails? ... |
|||
:
Нравится:
Не нравится:
|
|||
12.04.2004, 13:35 |
|
Explain and Indexes
|
|||
---|---|---|---|
#18+
Не путайте ключи analyze в командах vacuum и explain - у них разный смысл. В vacuum-е он обозначает сбор статистической инфы о таблице. В explain-е - реальное выполнение запроса и выдачу реальной статистики запроса наряду с предполагаемой. Подробнее смотрите в доках. "Вопрос: analyze собирает статистику для последующей оптимизации. Это значит что analyze нужно делать для всех запросов" Надо сделать лишь "vacuum analyze emails" или "vacuum analyze" для сбора статистики по всем таблицам в базе. Подробнее смотрите в доках. Результаты двух "explain analyze ...", которые вы привели получены после выполнения "vacuum analyze emails"? Вы сделали "vacuum analyze emails"? ... |
|||
:
Нравится:
Не нравится:
|
|||
12.04.2004, 13:53 |
|
Explain and Indexes
|
|||
---|---|---|---|
#18+
авторРезультаты двух "explain analyze ...", которые вы привели получены после выполнения "vacuum analyze emails"? Вы сделали "vacuum analyze emails"? После этой процедуры вот что получилось: # explain analyze select * from emails where category_id = 2; QUERY PLAN ---------------------------------------------------------------------------------------------------------------- Seq Scan on emails (cost=0.00..20322.01 rows=13333 width=28) (actual time=43.04..8796.18 rows=10130 loops=1) Filter: (category_id = 2) Total runtime: 8812.18 msec (записей: 3) # explain analyze select * from emails where category_id > 2; QUERY PLAN ------------------------------------------------------------------------------------------------------------------ Seq Scan on emails (cost=0.00..20322.01 rows=973914 width=28) (actual time=35.24..8336.33 rows=979922 loops=1) Filter: (category_id > 2) Total runtime: 9116.29 msec (записей: 3) Оптимизатор совсем отказался от индексирования? ... |
|||
:
Нравится:
Не нравится:
|
|||
12.04.2004, 14:02 |
|
Explain and Indexes
|
|||
---|---|---|---|
#18+
Как видно, теперь постгрес правильно предсказывает кол-во возвращаемых строк: (... rows=13333 ...) (actual ... rows=10130 ...) (... rows=973914 ...) (actual ... rows=979922 ...) Сделайте теперь пожалуйста: set enable_seq_scan to off; explain analyze select * from emails where category_id = 2; explain analyze select * from emails where category_id > 2; ... |
|||
:
Нравится:
Не нравится:
|
|||
12.04.2004, 14:21 |
|
Explain and Indexes
|
|||
---|---|---|---|
#18+
авторset enable_seq_scan to off; explain analyze select * from emails where category_id = 2; explain analyze select * from emails where category_id > 2; # explain analyze select * from emails where category_id = 2; QUERY PLAN ---------------------------------------------------------------------------------------------------------------- Seq Scan on emails (cost=0.00..20322.01 rows=13333 width=28) (actual time=43.04..8796.18 rows=10130 loops=1) Filter: (category_id = 2) Total runtime: 8812.18 msec (записей: 3) # explain analyze select * from emails where category_id > 2; QUERY PLAN ------------------------------------------------------------------------------------------------------------------ Seq Scan on emails (cost=0.00..20322.01 rows=973914 width=28) (actual time=35.24..8336.33 rows=979922 loops=1) Filter: (category_id > 2) Total runtime: 9116.29 msec (записей: 3) ... |
|||
:
Нравится:
Не нравится:
|
|||
12.04.2004, 14:28 |
|
Explain and Indexes
|
|||
---|---|---|---|
#18+
Сорри за очепятку. Сделайте пожалуйста: set enable_seqscan to off; explain analyze select * from emails where category_id = 2; explain analyze select * from emails where category_id > 2; ... |
|||
:
Нравится:
Не нравится:
|
|||
12.04.2004, 14:36 |
|
Explain and Indexes
|
|||
---|---|---|---|
#18+
Извиняюсь, наврал: вот правильные результаты: # explain analyze select * from emails where category_id = 2; QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------- Index Scan using emailsndx1 on emails (cost=0.00..47007.67 rows=13333 width=28) (actual time=158.83..42997.30 rows=10130 loops=1) Index Cond: (category_id = 2) Total runtime: 43037.43 msec (записей: 3) # explain analyze select * from emails where category_id > 2; а здесь psql виснет.... ... |
|||
:
Нравится:
Не нравится:
|
|||
12.04.2004, 14:41 |
|
Explain and Indexes
|
|||
---|---|---|---|
#18+
Сравните результаты запроса category_id = 2: без использования индекса: actual time=43.04..8796.18 с использованием индекса: actual time=158.83..42997.30 То есть в вашем случае постгрес все делает правильно: выбирает seq_scan, который и реально оказывается быстрее index_scan-а. "а здесь psql виснет" Не виснет, а задумывается. :-) Этот запрос отработает, думаю, за час с небольшим. ... |
|||
:
Нравится:
Не нравится:
|
|||
12.04.2004, 14:54 |
|
Explain and Indexes
|
|||
---|---|---|---|
#18+
Спасибо за помощь. А что вы можете сказать об этом: авторКакой тип индексов лучше использовать для внешних ключей? Я читал что индексы btree лучше использовать для числовых полей и полей типа дата/время. А hash - для текстовых полей. Также пишут что btree лучше подходит для операций <, > и сортировки, а hash - для = и <>. Внешний ключ - число, применяется операция =. Что выбрать? Таблица будет иметь несколько миллионов записей. И ещё несколько наболевших вопросов: 1) Правда ли что unique индексы быстрее, чем простые индексы? 2) При таких объёмах стоит ли индексировать поле типа boolen (имеется/отсутствует)? Может оно без индекса быстрее будет? 3) Стоит ли индексировать поле типа varchar(255) - наименование. По нему будет производится поиск с помощью оператора like (скорее всего на плное вхождение: '%template%')? Eсли стоит, то каким индексом? Hash? Очень нужна помощь в этом вопросе! Буду длагодарен любым советам. ... |
|||
:
Нравится:
Не нравится:
|
|||
12.04.2004, 14:59 |
|
Explain and Indexes
|
|||
---|---|---|---|
#18+
"Какой тип индексов лучше использовать"\r \r Я не экспериментировал с hash-индексами. Использую btree, которые создаются по дефолту.\r \r "unique индексы быстрее, чем простые индексы?"\r \r Не знаю. :-)\r \r "При таких объёмах стоит ли индексировать поле типа boolen"\r \r Если в таблице не будет "перекоса" по значениям в этом поле, то, думаю, постгрес такой индекс использовать никогда не будет, следовательно он не нужен.\r \r \'%template%\'\r \r В таком запросе индекс использовать бесполезно. ( В отличие например от \'template%\'. ) Можно или "вручную" разбивать тексты на слова и записывать их в отдельную таблицу, по которой затем искать по индексу запросом \'template%\'. Или попробовать воспользоваться модулем tsearch. ( Я им не пользовался. )\r /topic/53381&hl=tsearch ... |
|||
:
Нравится:
Не нравится:
|
|||
12.04.2004, 15:37 |
|
Explain and Indexes
|
|||
---|---|---|---|
#18+
hash индексы по-моему особо никем не используются и с ними могут быть проблемы. так что надо тестировать. на наболевшие вопросы: 1) вряд ли. выше шанс, что оптимизатор выберет Index Scan по уникальному индексу, особенно если забыть сделать VACUUM ANALYZE. 2) ни при каких. лучше посмотреть в сторону PARTIAL INDEX. 3) не стоит. для таких поисков нужен полнотекстовый поиск -> contrib/tsearch2 ... |
|||
:
Нравится:
Не нравится:
|
|||
12.04.2004, 16:14 |
|
|
start [/forum/topic.php?fid=53&fpage=358&tid=2007903]: |
0ms |
get settings: |
8ms |
get forum list: |
15ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
49ms |
get topic data: |
11ms |
get forum data: |
2ms |
get page messages: |
58ms |
get tp. blocked users: |
2ms |
others: | 324ms |
total: | 477ms |
0 / 0 |