Sybase ASE: Почему «ВЫБРАТЬ СЧЕТЧИК (*) ИЗ таблицы» занимает много минут
В Sybase ASE 16.0 на SuSE Linux есть растущая таблица с ~18 миллионами строк, которая имеет два индекса:
create INDEX ind_ig_bigstrings on ig_bigstrings(id,seq_id)
create INDEX ig_bigstrings_syb_id_col on ig_bigstrings( SYB_IDENTITY_COL )
А
select count(*) from ig_bigstrings
занимает ~ 5 минут, а второй запуск занимает всего 3 секунды. На плане видно, что индекс используется:
1> select count(*) from ig_bigstrings
2> go
QUERY PLAN FOR STATEMENT 1 (at line 1).
Optimized using Serial Mode
STEP 1
The type of query is SELECT.
2 operator(s) under root
|ROOT:EMIT Operator (VA = 2)
|
| |SCALAR AGGREGATE Operator (VA = 1)
| | Evaluate Ungrouped COUNT AGGREGATE.
| |
| | |SCAN Operator (VA = 0)
| | | FROM TABLE
| | | ig_bigstrings
| | | Index : ind_ig_bigstrings
| | | Forward Scan.
| | | Positioning at index start.
| | | Index contains all needed columns. Base table will not be read.
| | | Using I/O Size 4 Kbytes for index leaf pages.
| | | With LRU Buffer Replacement Strategy for index leaf pages.
-----------
18917916
Почему сканирование индекса занимает так много времени?
Кстати: я загрузил ту же таблицу на сервер PostgreSQL 13.1, и операция занимает всего 15 секунд, когда индекс не существует, и 2 секунды после создания индекса.
1 ответ
В общем, это могло быть связано с несколькими причинами (не исчерпывающий список):
- Таблица или ее индексы могут быть очень фрагментированными, в результате чего ее (производная) статистика будет очень низкой.
- Конкуренция ввода-вывода на дисковых устройствах или медленный ввод-вывод в целом.
- Кэш данных по умолчанию недостаточного размера для обработки такого количества данных.
- Большой пул ввода-вывода отсутствует или имеет недостаточный размер, в результате чего оптимизатор запросов вместо этого выбирает обычный пул ввода-вывода.
- В таблице много перенаправленных строк.
Глядя на план запроса, сценарий 1 кажется довольно маловероятным, так как это приведет к тому, что сканирование таблицы будет предпочтительнее обхода индекса оптимизатором запросов. Используйте оператор 'update statistics' для обновления статистики таблицы и / или индекса или используйте
Конфликт ввода-вывода или медленный дисковый ввод-вывод также будут ощущаться другими процессами в системе, так что это может быть предметом внимания.
Обычно одна или несколько строк таблицы хорошо помещаются на одной странице. Однако, поскольку на одной странице часто есть место для нецелого числа строк, Sybase ASE попытается уместить как можно больше этих строк на одной странице. Все, что не подходит, записывается на отдельную страницу, ссылка на которую размещается на исходной странице. Это называется перенаправленной строкой, и многие из них снижают производительность. Если таблица была создана совсем недавно и / или с тех пор содержимое не сильно изменилось, количество перенаправленных строк будет довольно небольшим. Однако, если в таблице было много вставок, удалений или обновлений, это число со временем будет неуклонно расти. Использовать
Однако наиболее вероятной причиной для меня является сценарий 3 или 4 или их комбинация. Тем более, что план запроса говорит нам, что он использует размер ввода-вывода 4 Кбайта. Размер страницы большого пула ввода-вывода часто в 8 раз превышает физический размер страницы (размер страницы, используемый для установки Sybase ASE). Для размера страницы 2 КБ (минимальный) это будет 16 КБ, для размера страницы 8 КБ это будет 64 КБ и так далее. Из текста плана запроса я полагаю, что для этого сервера используется размер страницы 4K. Использовать: