Гость
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / неиспользование индексов в Pg. 7.3 / 24 сообщений из 24, страница 1 из 1
07.07.2003, 17:43
    #32201254
m_dance
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
неиспользование индексов в Pg. 7.3
Hello All!

тема старая но увы актуальная :( постгрес не хочет использовать
индексы, хотя их использовать точно надо. В частости, при SELECT count(*) ..

Таблица имеет нормальный PK и ес-но индексирован, тем не менее EXPLAIN
показывается Seq Scan:

=> explain select count(*) from tbl_yy;
QUERY PLAN
------------------------------------------------------------------
Aggregate (cost=184.00..184.00 rows=1 width=0)
-> Seq Scan on tbl_yy (cost=0.00..159.00 rows=10000 width=0)

Для таблиц в неск. миллионов записей это весьма напрягает. ANALYZE разумеется делается, но постгресу это монопенисуально..
...
Рейтинг: 0 / 0
10.07.2003, 12:21
    #32204251
LeXa NalBat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
неиспользование индексов в Pg. 7.3
"их использовать точно надо"

Использование индекса в этом запросе не может дать кардинального ускорения, потому что нет условия "where" и посчитать надо все! записи в таблице, так какая разница - пробегать весь миллион записей по таблице или по индексу?

Можно заставить постгрес использовать индекс в таком запросе:

# explain select count(*) from test_table;
Aggregate (cost=99704.51..99704.51 rows=1 width=0)
-> Seq Scan on test_table (cost=0.00..88396.01 rows=4523401 width=0)

# set enable_seqscan to off;

# explain select count(id) from ( select id from test_table order by id ) as a;
Aggregate (cost=17753473.89..17753473.89 rows=1 width=4)
-> Subquery Scan a (cost=0.00..17742165.38 rows=4523401 width=4)
-> Index Scan using test_index on test_table (cost=0.00..17742165.38 rows=4523401 width=4)

Однако это будет работать намного! дольше (например на таблице в миллион записей) чем seq_scan, потому что для каждой записи найденной по индексу постгрес будет вытягивать соответствующую строку из таблицы.

P.S.: Оракл использует для такого запроса индекс, и выполняет его быстрее, чем seq_scan из-за того, что для каждой записи найденной по индексу он не! вытягивает строку из таблицы, а считает (count) прямо по записи из индекса. А пробежать по индексу немного! быстрее, чем по таблице, если, например, в нем проиндексированы не все поля таблицы.

ID Operation Object UP Cost
---- ---------------------------------------- ----------------- --- ------
0 SELECT STATEMENT, 1526
1 SORT, AGGREGATE 0 1
2 INDEX, FAST FULL SCAN TEST_TABLE 1 1
...
Рейтинг: 0 / 0
10.07.2003, 15:35
    #32204673
m_dance
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
неиспользование индексов в Pg. 7.3
>>"их использовать точно надо"
sic!

>>Использование индекса в этом запросе не может дать кардинального >>ускорения, потому что нет условия "where" и посчитать надо все! записи >>в таблице, так какая разница - пробегать весь миллион записей по >>таблице или по индексу?
разница существенная - идексы обычно значительно меньше, т.е. операций
READ меньше на порядки

>>Можно заставить постгрес использовать индекс в таком запросе:

>># explain select count(*) from test_table;
>>Aggregate (cost=99704.51..99704.51 rows=1 width=0)
>>-> Seq Scan on test_table (cost=0.00..88396.01 rows=4523401 width=0)
>>
>># set enable_seqscan to off;
>>
>># explain select count(id) from ( select id from test_table order by id ) as a;
>>Aggregate (cost=17753473.89..17753473.89 rows=1 width=4)
>>-> Subquery Scan a (cost=0.00..17742165.38 rows=4523401 width=4)
>>-> Index Scan using test_index on test_table (cost=0.00..17742165.38 >>rows=4523401 width=4)

>>Однако это будет работать намного! дольше (например на таблице в >>миллион записей) чем seq_scan, потому что для каждой записи найденной >>по индексу постгрес будет вытягивать соответствующую строку из >>таблицы.
это совсем не то запрос, который предлагался


>>P.S.: Оракл использует для такого запроса индекс, и выполняет его >>быстрее, чем seq_scan из-за того, что для каждой записи найденной по >>индексу он не! вытягивает строку из таблицы, а считает (count) прямо по
ИМЕННО, и это есть нормальное поведение. Откуда сведения, что постгрес так не делает? Ссылку в студию!
...
Рейтинг: 0 / 0
10.07.2003, 16:37
    #32204775
LeXa NalBat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
неиспользование индексов в Pg. 7.3
"разница существенная - идексы обычно значительно меньше, т.е. операций READ меньше на порядки"

"Существенная" (~10), но не "кардинальная" (~1000) (как например для запросов с ограничением). (Это не обозначает, что я голосую за то, чтобы постгрес не улучшил свое поведение в этом вопросе.)

"это совсем не то запрос, который предлагался"

Возможно. Этот кажется более похожим (в таблице все id>=0):

# set enable_seqscan to off;
# explain select count(id) from test_table where id >= 0;
Aggregate (cost=17763139.20..17763139.20 rows=1 width=4)
-> Index Scan using test_index on test_table (cost=0.00..17751831.75 rows=4522982 width=4)

(Однако его цена по оценке постгреса очень похожа на предыдущий: 17763139.20 и 17753473.89).

Но и окончания его выполнения у меня не хватило терпения дождаться. В то время как seq_scan отработал за приемлемое время.

"ИМЕННО, и это есть нормальное поведение."

Согласен.

"Откуда сведения, что постгрес так не делает? Ссылку в студию!"

Только из опыта. Могу предложить вам задать вопрос на postgresql.org.
...
Рейтинг: 0 / 0
10.07.2003, 18:34
    #32204928
Sad Spirit
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
неиспользование индексов в Pg. 7.3
Постгрес действительно при поиске по индексу будет выдёргивать запись из таблицы. Причина простая: информация о видимости записи для текущей транзакции хранится именно в таблице, в индексе её нет.

Что касается исходного вопроса, то можно повесить на tbl_yy триггер, который будет собирать статистику о кол-ве записей в таблице и сохранять её где-нибудь.
...
Рейтинг: 0 / 0
11.07.2003, 10:55
    #32205295
m_dance
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
неиспользование индексов в Pg. 7.3
>>Постгрес действительно при поиске по индексу будет выдёргивать запись >>из таблицы. Причина простая: информация о видимости записи для >>текущей транзакции хранится именно в таблице, в индексе её нет.

зачем знать о видимости (доступности?) записи при операции count() ?
...
Рейтинг: 0 / 0
11.07.2003, 23:56
    #32206254
Sad Spirit
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
неиспользование индексов в Pg. 7.3
m_dance
> зачем знать о видимости (доступности?) записи при операции count() ?

чтобы не сосчитать заодно удалённые записи и старые версии изменённых.
...
Рейтинг: 0 / 0
14.07.2003, 11:04
    #32206825
m_dance
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
неиспользование индексов в Pg. 7.3
что ж это за индекс такой, который не соответствует текущему состоянию таблицы? :-F

что касается удалённых - пока не было коммита, запись считается существующей, и индекс соответсвенно тоже. как только коммит сказал, индекс тоже перестраивается.
...
Рейтинг: 0 / 0
14.07.2003, 15:08
    #32207287
Sad Spirit
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
неиспользование индексов в Pg. 7.3
m_dance
> что касается удалённых - пока не было коммита, запись считается существующей, и индекс соответсвенно тоже. как только коммит сказал, индекс тоже перестраивается.

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; -- и что дальше?

А вообще лучше эти вопросы адресовать в список рассылки pgsql-general, его разработчики читают, они лучше объяснить смогут.
...
Рейтинг: 0 / 0
15.07.2003, 10:51
    #32207989
m_dance
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
неиспользование индексов в Pg. 7.3
>> что касается удалённых - пока не было коммита, запись считается
>>существующей, и индекс соответсвенно тоже. как только коммит сказал,
>>индекс тоже перестраивается.

>SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; -- и что дальше?

в огороде бузина, а в киеве дядька, что называется.. Изменение индексов привязано к изменению данных в транзакции. Монопенисуально, обычная это транзакция или автономная. Всё остально относится к умению или неумению использовать эти самые TRANSACTION ISOLATION

>А вообще лучше эти вопросы адресовать в список рассылки pgsql-general,
>его разработчики читают, они лучше объяснить смогут.
всегда удивляла позиция "сказать нечего но очень хочется поэтому скажу хоть что-нибудь"
...
Рейтинг: 0 / 0
15.07.2003, 13:52
    #32208324
Sad Spirit
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
неиспользование индексов в Pg. 7.3
m_dance
>>SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; -- и что дальше?

> в огороде бузина, а в киеве дядька, что называется.. Изменение индексов привязано к изменению данных в транзакции. Монопенисуально, обычная это транзакция или автономная. Всё остально относится к умению или неумению использовать эти самые TRANSACTION ISOLATION

Чё-то на вопрос ты не ответил, хотя и наговорил много. "сказать нечего но очень хочется поэтому скажу хоть что-нибудь"? :)

> всегда удивляла позиция "сказать нечего но очень хочется поэтому скажу хоть что-нибудь"

на твой исходный вопрос я ответил. если тебе ответ не нравится --- твои проблемы. а в потрошках я разбираюсь плохо --- оттого и отсылка к разработчикам.
...
Рейтинг: 0 / 0
15.07.2003, 15:26
    #32208516
m_dance
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
неиспользование индексов в Pg. 7.3
расшифруй свою мысль про SET TRANSACTION .. и тогда получшь наглядное разъяснение
...
Рейтинг: 0 / 0
16.07.2003, 00:34
    #32209114
Sad Spirit
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
неиспользование индексов в Pg. 7.3
m_dance
> расшифруй свою мысль про SET TRANSACTION .. и тогда получшь наглядное разъяснение

длинно получится, ну да ладно.

пусть у нас есть табличка counter, содержащая две записи

стандартное поведение, уровень read commited:
Код: 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.
консоль  1 :
test=# begin work;
BEGIN

консоль  2 :
test=# begin work;
BEGIN
test=# delete from counter where id =  1 ;
DELETE  1 

консоль  1 :
test=# select count(*) from counter;
 count
 -------
 
      2 
( 1  row)

консоль  2 :
test=# commit work;
COMMIT

консоль  1 :
test=# select count(*) from counter;
 count
 -------
 
      1 
( 1  row)



уровень serializable:
Код: 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.
консоль  1 :
test=# begin work;
BEGIN
test=# set transaction isolation level serializable;
SET VARIABLE

консоль  2 :
test=# begin work;
BEGIN
test=# set transaction isolation level serializable;
SET VARIABLE
test=# delete from counter where id =  1 ;
DELETE  1 

консоль  1 :
test=# select count(*) from counter;
 count
 -------
 
      2 
( 1  row)

консоль  2 :
test=# commit work;  -- вот здесь мы должны перестроить индекс, так?
 
COMMIT

консоль  1 :
test=# select count(*) from counter;  -- а вот здесь - обломаться, увидев %af_src_str_0 вместо %af_src_str_1?
 
 count
 -------
 
      2 
( 1  row)

...
Рейтинг: 0 / 0
16.07.2003, 00:36
    #32209115
Sad Spirit
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
неиспользование индексов в Pg. 7.3
форум колбасит. следует читать "увидев '1' вместо '2'"
...
Рейтинг: 0 / 0
16.07.2003, 11:18
    #32209421
m_dance
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
неиспользование индексов в Pg. 7.3
нда.. количество не перешло в качество :]
ты можешь хотя бы для себя КРАТКО сформулировать свою мысль? не примеры приводить, а ИДЕЮ.

так что пока я могу только ПРЕДПОЛОЖИТЬ, что ты настаивашь на том, что понятие транзакции работает по-разному для собственно табличных данных и для индексов, так что ли?
...
Рейтинг: 0 / 0
16.07.2003, 11:58
    #32209481
Sad Spirit
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
неиспользование индексов в Pg. 7.3
m_dance
> ты можешь хотя бы для себя КРАТКО сформулировать свою мысль? не примеры приводить, а ИДЕЮ.

Идея простая: поведение базы при уровнях изоляции READ COMMITED и SERIALIZABLE должно различаться, см. пример (который, видимо, оказался для тебя слишком сложным). И если при READ COMMMITED твоё "решение" --- "как только коммит сказал, индекс тоже перестраивается" --- ещё прокатывает, то при SERIALIZABLE нет.

Если ты не знаешь, что такое "уровни изоляции", то КРАТКО объяснить не получится, уж извини. Купи книжку.

> что понятие транзакции работает по-разному для собственно табличных данных и для индексов

Ну-ка, расскажи-ка поподробнее про "понятие транзакции для индексов". Будет весьма забавно послушать.
...
Рейтинг: 0 / 0
16.07.2003, 15:59
    #32209948
m_dance
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
неиспользование индексов в Pg. 7.3
дружище! в сад.

почитай как ЭТО делает в приличных базах. например, Oracle

p.s. агрессивные пионеры хуже геморроя
...
Рейтинг: 0 / 0
16.07.2003, 22:41
    #32210325
Sad Spirit
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
неиспользование индексов в Pg. 7.3
m_dance
> агрессивные пионеры хуже геморроя

Извини, папаша , что обидел. Это по глупости и малолетству. Больше не буду!
...
Рейтинг: 0 / 0
18.08.2003, 18:49
    #32239541
oai-ash
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
неиспользование индексов в Pg. 7.3
Прочитал все сообщения и не увидел ответа на поставленный вопрос. Попытаюсь его немного перефразировать:

И все таки, почему Postgres не отдает count по миллионной таблице так как это делают Oracle и MySQL? В миллисекунды?

Я недавно начал изучать Postgres имея довольно солидный опыт работы с вышеупомянутыми базами данных, поэтому столкнувшись с тем, что получение количества записей в милионной таблице занимает около 7 секунд, честно говоря, пришел в недоумение.

Кто нибудь вообще может поделиться личным опытом сравнения скорости работы Postgres с другими RDBMS?
...
Рейтинг: 0 / 0
22.08.2003, 13:07
    #32244542
LeXa NalBat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
неиспользование индексов в Pg. 7.3
"не увидел ответа на поставленный вопрос"\r
\r
Ответ на вопрос в топике есть: "потому что для каждой записи найденной по индексу постгрес будет вытягивать соответствующую строку из таблицы", "oracle ... не! вытягивает строку из таблицы, а считает (count) прямо по записи из индекса".\r
\r
Нет ответа на вопрос: "почему бы Постгресу не действовать в этом запросе аналогично Ораклу?"\r
\r
"Кто нибудь вообще может поделиться личным опытом сравнения скорости работы Postgres с другими RDBMS?"\r
\r
Мне кажется, что нужно сравнивать не только скорость. /topic/26963
...
Рейтинг: 0 / 0
21.09.2003, 17:05
    #32271146
Vladimir Dozen
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
неиспользование индексов в Pg. 7.3
Мда... мало того, что count(*) использует full scan,
так еще и выражения типа where parent_id = XXX;
индекс не используют! тоже full scan. При этом,
поиск в той же таблице по name LIKE 'foo%' индекс
используют в полный рост, и работает 0.08 секунды
вместо двух в случае parent_id...

То есть, более внятно -- есть таблица t_tree.
Миллион с небольшим записей. В ней несколько
полей, среди который id, parent_id и name. Есть
два индекса -- по parent_id и по name.

explain select * from t_tree where parent_id=123;

говорит, что будет full scan. Сам запрос занимает две секунды.

explain select * from t_tree where name like 'foo%';

говорит, что использует индекс, и сам запрос требует 0.08.

Кошмарик...

По-моему, это бага.
...
Рейтинг: 0 / 0
21.09.2003, 17:09
    #32271147
Vladimir Dozen
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
неиспользование индексов в Pg. 7.3
А вот, собственно, и объяснение:

=======================
PostgreSQL 7.2 will allways do a full table scan when the index field is
a bigint. It will also perform a full table scan when only an upper or a
lower bound is given for an int4 index. If you specify a range (where
key > 12 and key < 99) it will use the index.
For bigint keys even an "where bigkey = 99" will cause a full table scan!
=======================

Короче, id надо было не int8 делать, а int4...

P.S. Но это все равно бага, IMHO.
...
Рейтинг: 0 / 0
22.09.2003, 10:33
    #32271361
assa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
неиспользование индексов в Pg. 7.3
Ой. Ну мы попали :0)

И шо нам посоветуют бывалые люди? Строить индекс на текстовую функцию от поля int8 и его юзать? благо в букварях вроде было упоминание о возможности построить индекс на ф-ю. Или они иначе извращаются?
...
Рейтинг: 0 / 0
22.09.2003, 12:30
    #32271555
Sad Spirit
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
неиспользование индексов в Pg. 7.3
бывалые люди посоветуют приводить константу к типу:
WHERE id = 99::int8
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / неиспользование индексов в Pg. 7.3 / 24 сообщений из 24, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]