Всем привет.
Есть БД MySQL и таблица 3 млн. записей, и стандартный GridView. При подсчёте getTotalCount идёт очень долгий запрос из БД.
Запрос через модель поиска, предлагать статические значения не стоит.
Кто как решил или решал данную проблему?
GridView выбор всех данных
Re: GridView выбор всех данных
Сам запрос, те данные, что выводятся, наверное, медленный?
Общее число там же не хитро считается - count(*) без сортировок и офсетов с лимитами.
Гляньте explain
Общее число там же не хитро считается - count(*) без сортировок и офсетов с лимитами.
Гляньте explain
Re: GridView выбор всех данных
В том то и проблема, что запрос идёт на лимит 20 и срабатывает очень быстро, а вот count(*) работает медленно и может срабатывать до кэширования от 7 до 15 секунд, если не 30+ иногда может быть
P.S. Самый обыкновенный запрос
Код: Выделить всё
SELECT COUNT(*) FROM (SELECT * FROM `clients` `cl` GROUP BY `cl`.`id`) `c`
Код: Выделить всё
$tQuery = clone $query;
$total = $tQuery->select(['COUNT(DISTINCT ' . Clients::TABLE_ALIAS . '.id)'])->count();
$dataProvider->setTotalCount($total);
Re: GridView выбор всех данных
А я вот не помню, оно count вот так делает, подставляет слева от того запроса, что в $dataProvider->query ?SELECT COUNT(*) FROM (SELECT * FROM `clients` `cl` GROUP BY `cl`.`id`) `c`
Видно же что тут куча ненужной работы, зачем все это группировать, и выбирать все столбцы, чтобы посчитать потом число строк.
Я уже думал над таким, у меня query обычно навороченные, и вот эту целесообразность для подсчета всех строк использовать изначальный $query, а не посчитать самому, вот как вы вручную посчитали
Re: GridView выбор всех данных
Вы сразу узнали, что у вас в таблице 1 млн записей, установили в гриде фильтр на фамилию, вам нужно узнать сколько у вас Ивановых в списке. Он вам тот же миллион вернёт? Или все же, например, 100 Ивановых. Установили имя Василий и узнали, что Иванов Василий у вас один, а не миллион
Вот для этой вещи и подсчитывается count для результирующего запроса, а не первоначального. И такая конструкция, как я написал, мне помогла решить в сокращении нагрузки и тем самым быстрее отдавать значение.
Суть в том, что я установил значение в запрос, который отработал шустрее, чем мог бы.
Re: GridView выбор всех данных
все, что влияет на выборку(where, group by, distinct и т.д.), естественно остается, но и тут исключения - вы же сами в своем решении выяснили что distinct отработал у вас быстрее чем group by, который в изначальном запросе
Re: GridView выбор всех данных
В изначальном запросе изменяется селект, остальные условия остались неизменными в запросе. И важно, что устанавливается тотал с этим запросом, а не запросом дата провайдера. Попробуйте где-нибудь на своём проекте это решение. Расскажете результат. Важно чтобы таблица с многомиллионными записями из mysql грузилась быстро. Индексы в расчёт не берём, считаем, что они правильно выставлены.