23 / 23 / 11
Регистрация: 05.02.2010
Сообщений: 314
|
|
1 | |
Как можно увеличить скорость подсчета строк в таблице19.06.2013, 00:52. Показов 6354. Ответов 15
Метки нет (Все метки)
Доброй ночи.
Есть таблица на 9500000 строк как можно увеличить скорость подсчета строк в таблице если по одному параметру может выбрать 8999999 строк.
0
|
19.06.2013, 00:52 | |
Ответы с готовыми решениями:
15
Как увеличить скорость вычислений 500 000 строк? Как увеличить скорость добавления строк на листе Excel Можно ли увеличить скорость ответа БД Можно ли увеличить скорость парсинга в HtmlAgilityPack? |
1251 / 967 / 382
Регистрация: 02.09.2012
Сообщений: 2,989
|
|
19.06.2013, 16:57 | 2 |
построить план запроса (EXPLAIN)... от него уже плясать
0
|
23 / 23 / 11
Регистрация: 05.02.2010
Сообщений: 314
|
|
19.06.2013, 21:33 [ТС] | 3 |
не совсем понятно что он показывает, есть где то расшифровка?
Добавлено через 39 минут Вот план, можно перевести "Hash Join (cost=2.27..676918.63 rows=9020883 width=1166) (actual time=0.051..31650.458 rows=8999999 loops=1)" " Hash Cond: (f.screen_version_id = sv.id)" " -> Nested Loop (cost=1.11..552880.33 rows=9020883 width=654) (actual time=0.030..28141.769 rows=8999999 loops=1)" " -> Seq Scan on tbl_release r (cost=0.00..1.25 rows=1 width=8) (actual time=0.007..0.009 rows=1 loops=1)" " Filter: (id = 15)" " Rows Removed by Filter: 19" " -> Hash Join (cost=1.11..462670.25 rows=9020883 width=654) (actual time=0.018..26458.778 rows=8999999 loops=1)" " Hash Cond: (f.type_film_id = tf.id)" " -> Seq Scan on tbl_films f (cost=0.00..338632.00 rows=9020883 width=142) (actual time=0.005..22186.697 rows=8999999 loops=1)" " Filter: (release_id = 15)" " Rows Removed by Filter: 500002" " -> Hash (cost=1.05..1.05 rows=5 width=520) (actual time=0.006..0.006 rows=5 loops=1)" " Buckets: 1024 Batches: 1 Memory Usage: 1kB" " -> Seq Scan on tbl_type_films tf (cost=0.00..1.05 rows=5 width=520) (actual time=0.002..0.003 rows=5 loops=1)" " -> Hash (cost=1.07..1.07 rows=7 width=520) (actual time=0.014..0.014 rows=7 loops=1)" " Buckets: 1024 Batches: 1 Memory Usage: 1kB" " -> Seq Scan on tbl_screen_version sv (cost=0.00..1.07 rows=7 width=520) (actual time=0.007..0.009 rows=7 loops=1)" "Total runtime: 32230.258 ms"
0
|
1251 / 967 / 382
Регистрация: 02.09.2012
Сообщений: 2,989
|
|
22.06.2013, 16:04 | 4 |
Не мог я сразу ответить, если еще актуально!
Отступы потеряли! Это важно для понимания структуры плана. Простые рекомендации, если лень читать доки. 1. Обращайте внимание на "actual time" и стрелочками помечены операции, которые исполнитель запроса делает для получения результатов вашего запроса. 2. Seq Scan - последовательный поиск по таблице! ПЛОХО! Проверьте индексы по полю, которое ниже строчкой стоит под Filter. Индекс выгоднее использовать. 3. Не понятно, откуда взялся Nested Loop (вложенный цикл, то есть перебор записей). У вас что таблицы в запросе не связаны? Это ПЛОХО! Остальное уже мало времени занимает, пока пропустим
0
|
23 / 23 / 11
Регистрация: 05.02.2010
Сообщений: 314
|
|
23.06.2013, 14:35 [ТС] | 5 |
0
|
1251 / 967 / 382
Регистрация: 02.09.2012
Сообщений: 2,989
|
|
23.06.2013, 17:49 | 6 |
Nested Loop: Базе приходится перелапачивать n*m итераций для объединения двух таблиц с n и m записями. Nested Loop хорошо для маленьких таблиц - быстрее выполняется, чем Hash Join, так как не нужно строить хэши для объединения, но для больших таблиц - это фактически гарантировано тормоза.
0
|
23 / 23 / 11
Регистрация: 05.02.2010
Сообщений: 314
|
|
24.06.2013, 18:20 [ТС] | 7 |
Вот новый, если можно про комментировать
"Aggregate (cost=342640.87..342640.88 rows=1 width=4) (actual time=407536.830..407536.830 rows=1 loops=1)" " -> Bitmap Heap Scan on tbl_films f (cost=67247.68..335103.51 rows=3014946 width=4) (actual time=404609.514..407143.771 rows=2999999 loops=1)" " Recheck Cond: (release_id = 7)" " Rows Removed by Index Recheck: 119" " -> Bitmap Index Scan on index_tbl_films_release_id (cost=0.00..66493.95 rows=3014946 width=0) (actual time=404607.541..404607.541 rows=3000000 loops=1)" " Index Cond: (release_id = 7)" "Total runtime: 407537.071 ms"
0
|
1251 / 967 / 382
Регистрация: 02.09.2012
Сообщений: 2,989
|
|
26.06.2013, 07:17 | 8 |
Bitmap Index имеет ограниченные условия применения (в основном для данных, которые очень редко меняются, ибо существенные накладные расходы на создание и поддержание целостности индекса)
См. например здесь и здесь Попробуйти заменить на обычный b-tree индекс у соответствующих таблиц. И покажите сам запрос. Не понимаю почему делается heap scan и index scan. Не могу представить, как это в запросе может выглядеть.
0
|
23 / 23 / 11
Регистрация: 05.02.2010
Сообщений: 314
|
||||||||||||||||
26.06.2013, 23:43 [ТС] | 9 | |||||||||||||||
0
|
1251 / 967 / 382
Регистрация: 02.09.2012
Сообщений: 2,989
|
||||||
01.07.2013, 23:32 | 10 | |||||
Был в отъезде... неудобно отвечать было... опять же, если еще актуально
1. Не знаю какая версия у вас postgres, но можете прочитать этот мануал 2. Сделать VACUUM tbl_film, как там написано + включить indexscanonly, если соотв. версия postgres. 3. Я провел эксперименты над таблицей в 9 млн. записей. Указанными выше способами довел выполнение запроса с 17000 ms (seq scan без индексов), до 0,170 ms (индексы, плюс кеширование уже помогало быстро выбирать результаты на запрос).
Код
"Aggregate (cost=235677.39..235677.40 rows=1 width=0) (actual time=3387.151..3387.152 rows=1 loops=1)" " -> Seq Scan on tbl_film (cost=0.00..233215.00 rows=984956 width=0) (actual time=0.039..2439.000 rows=1001693 loops=1)" " Filter: (film_releaseid = 7)" " Rows Removed by Filter: 8004307" "Total runtime: 3387.195 ms" Код
"Aggregate (cost=153852.99..153853.00 rows=1 width=0) (actual time=4076.851..4076.852 rows=1 loops=1)" " -> Bitmap Heap Scan on tbl_film (cost=18438.65..151390.60 rows=984956 width=0) (actual time=144.397..3146.587 rows=1001693 loops=1)" " Recheck Cond: (film_releaseid = 7)" " Rows Removed by Index Recheck: 7424552" " -> Bitmap Index Scan on index_film_releaseid (cost=0.00..18192.41 rows=984956 width=0) (actual time=142.885..142.885 rows=1001693 loops=1)" " Index Cond: (film_releaseid = 7)" "Total runtime: 4077.050 ms" Включаем, все что написано в 1 и 2 Код
"Aggregate (cost=31396.39..31396.40 rows=1 width=0) (actual time=2000.319..2000.320 rows=1 loops=1)" " -> Index Only Scan using index_film_releaseid on tbl_film (cost=0.00..28934.00 rows=984956 width=0) (actual time=0.056..1220.871 rows=1001693 loops=1)" " Index Cond: (film_releaseid = 7)" " Heap Fetches: 277" "Total runtime: 2000.362 ms" Вообщем мораль, если нет частых (и массивных) изменений данных, то включить сканирование по индексу, вакуумизировать, также не создавать излишних (которые не участвуют в оптимизации запросов) индексов - это тоже отнимает время Все результаты приведены для домашнего ноута (Core2Duo, 2,5Ghz, postgresql 9.2.4, поставлен в Gentoo из portage без каких-либо извратов)
0
|
23 / 23 / 11
Регистрация: 05.02.2010
Сообщений: 314
|
|
09.07.2013, 00:35 [ТС] | 11 |
1. С английским проблема.
2. vacuum сделал, а где включить indexscanonly (версия 9.2.4.1). 3. Как лучше сделать индексы по каждому поисковому полю или один составной индекс? Как можно настроить кеширование запросов?
0
|
1251 / 967 / 382
Регистрация: 02.09.2012
Сообщений: 2,989
|
|
09.07.2013, 16:50 | 12 |
Это проблема. Боюсь на русском такой информации еще не найти. Ну автопереводчики вам в помощь, хотя от них бывает мало толку. В разделе index-only scans (я бы перевел как "Поиск только с использование индексов") кратко написано
1. Сделать обычный индекс (без указания алгоритма) для таблицы по тем полям, которые участвуют в where 2. Сделать вакуумизацию 3. Включить "поиск только с использованием индексов" Да вообще-то indexonlyscan уже должна быть включена по умолчанию (как пишут в документации). Но попробуйте через pgadmin или через psql дать команду SET enable_indexscanonly to ON. Это должно настроить планировщик выполнения запросов на использование соответствующего индекса. Лучше создавать такие индексы, которые соответствуют выражению WHERE. То есть, если отбираем записи только по releaseid, то и индекс нужен только по этому полю, если по releaseid и screenid, то и индекс по этим двум полям. Опять же правило, чем больше индексов, тем больше времени тратиться на их перестроение при изменении данных (INSERT, DELETE, UPDATE). Обязательно сверяйте использование индексов с планом. Если видите, что планировщик выполнения запросов построил какой-то неверный план выполнения, значит где-то ошибка. Кэширование как-таковое уже включено. То есть если дважды выполнить один и тот же запрос, то результаты для второго запроса результаты появятся гораздо быстрее. Для многопользовательского режима это может быть актуально. Если пользователи часто запрашивают одни и те же данные, не нужно по многу раз перевыполнять один и тотже запрос. Резульаты возмуться из кеша, если данные не изменялись конечно. Упралвять кеширование можно через параметры управления сервером. Об этом написана целая глава 18 в документации. На русском даже не знаю, есть или нет. Спрашивайте, если потребуется, попробуем разобраться.
0
|
23 / 23 / 11
Регистрация: 05.02.2010
Сообщений: 314
|
|
09.07.2013, 18:32 [ТС] | 13 |
то есть если у меня например пять поисковых полей то мне нужно создать на каждое поле индекс, а затем перебирать возможные комбинации фильтра? А если требуется возможность динамического добавления и удаления фильтра?
0
|
1251 / 967 / 382
Регистрация: 02.09.2012
Сообщений: 2,989
|
|
09.07.2013, 23:29 | 14 |
С динамическим фильтром может быть проблема: или гибкость или скорость. Обычно одно другое взаимоисключает. Но лучше всего протестировать! Если производительность устроит, значит индексы оставить как есть. Если нет, то тогда придется как-то менять модель данных, чтобы справиться с большим объемом данных и одновременно обеспечивать соотв. уровень гибкости фильтров при выборке.
0
|
23 / 23 / 11
Регистрация: 05.02.2010
Сообщений: 314
|
|
10.07.2013, 14:33 [ТС] | 15 |
Для хранения списка жанров к фильму есть таблица связи в ней есть поле film_id и genre_id. При выборке например по "году выпуска" и жанру "ужасы" можно как то склеить поле из таблицы tbl_films.id с таблицей tbl_relations.film_id чтоб быстро получить количество строк соответствующему условию. Сейчас выполняется за 4,5с., а если отдельно выполнить запрос для получения количества строк только по жанру то запрос выполняется за 0,4с.
0
|
1251 / 967 / 382
Регистрация: 02.09.2012
Сообщений: 2,989
|
||||||||||||||||||||||||||
01.08.2013, 18:33 | 16 | |||||||||||||||||||||||||
Гм-гм... времени правда прошло три недели, но не мог я раньше ответить.
При оптимизации запросов пока (IMHO) лучше не придумали подхода, чем смотреть, что показывает план запроса - в нем мы видим, как СУБД выполняет запрос (как она "думает" и совпадает ли ее "думанье" с нашим). Мне сложно точно воспроизвести ситуацию, потому что я не знаю ни вашей модели данных, ни ваших данных, но попробую показать на простом примере. У меня остались предыдущие данные (9 млн. записей), я к ним приделал таблицу genre. Вот так:
Запускаю анализ плана:
Проверяем, что это так и есть: Видим 1,4 с. Много! Создаем индекс для условия genre_id=8
Получилось где-то раз в 10 быстрее. Надеюсь алгоритм действий понятен. Много зависит от организации модели данных и запросов, которые строятся по этой модели. Будут вопросы, присылайте.
0
|
01.08.2013, 18:33 | |
01.08.2013, 18:33 | |
Помогаю со студенческими работами здесь
16
Максимальная скорость беспроводного соединения: 54 Мбит/с - можно ли увеличить ее? Можно ли увеличить скорость на мамке Shuttle AB52 USB1.1 до USB2.0? Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |