GridView выбор всех данных

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
unknownby
Сообщения: 749
Зарегистрирован: 2019.11.05, 16:34
Контактная информация:

GridView выбор всех данных

Сообщение unknownby »

Всем привет.

Есть БД MySQL и таблица 3 млн. записей, и стандартный GridView. При подсчёте getTotalCount идёт очень долгий запрос из БД.
Запрос через модель поиска, предлагать статические значения не стоит. :)

Кто как решил или решал данную проблему?
Аватара пользователя
maleks
Сообщения: 1985
Зарегистрирован: 2012.12.26, 12:56

Re: GridView выбор всех данных

Сообщение maleks »

Сам запрос, те данные, что выводятся, наверное, медленный?

Общее число там же не хитро считается - count(*) без сортировок и офсетов с лимитами.

Гляньте explain
Yii2 universal module sceleton - for basic and advanced templates
unknownby
Сообщения: 749
Зарегистрирован: 2019.11.05, 16:34
Контактная информация:

Re: GridView выбор всех данных

Сообщение unknownby »

maleks писал(а): 2021.12.07, 08:53 Сам запрос, те данные, что выводятся, наверное, медленный?

Общее число там же не хитро считается - count(*) без сортировок и офсетов с лимитами.

Гляньте explain
В том то и проблема, что запрос идёт на лимит 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);
Странно, но запрос стал работать быстрее. В раз 10
Аватара пользователя
maleks
Сообщения: 1985
Зарегистрирован: 2012.12.26, 12:56

Re: GridView выбор всех данных

Сообщение maleks »

SELECT COUNT(*) FROM (SELECT * FROM `clients` `cl` GROUP BY `cl`.`id`) `c`
А я вот не помню, оно count вот так делает, подставляет слева от того запроса, что в $dataProvider->query ?

Видно же что тут куча ненужной работы, зачем все это группировать, и выбирать все столбцы, чтобы посчитать потом число строк.

Я уже думал над таким, у меня query обычно навороченные, и вот эту целесообразность для подсчета всех строк использовать изначальный $query, а не посчитать самому, вот как вы вручную посчитали
Yii2 universal module sceleton - for basic and advanced templates
unknownby
Сообщения: 749
Зарегистрирован: 2019.11.05, 16:34
Контактная информация:

Re: GridView выбор всех данных

Сообщение unknownby »

maleks писал(а): 2021.12.08, 16:13 Я уже думал над таким, у меня query обычно навороченные, и вот эту целесообразность для подсчета всех строк использовать изначальный $query, а не посчитать самому, вот как вы вручную посчитали
Вы сразу узнали, что у вас в таблице 1 млн записей, установили в гриде фильтр на фамилию, вам нужно узнать сколько у вас Ивановых в списке. Он вам тот же миллион вернёт? Или все же, например, 100 Ивановых. Установили имя Василий и узнали, что Иванов Василий у вас один, а не миллион :)
Вот для этой вещи и подсчитывается count для результирующего запроса, а не первоначального. И такая конструкция, как я написал, мне помогла решить в сокращении нагрузки и тем самым быстрее отдавать значение.

Суть в том, что я установил значение в запрос, который отработал шустрее, чем мог бы.
Аватара пользователя
maleks
Сообщения: 1985
Зарегистрирован: 2012.12.26, 12:56

Re: GridView выбор всех данных

Сообщение maleks »

все, что влияет на выборку(where, group by, distinct и т.д.), естественно остается, но и тут исключения - вы же сами в своем решении выяснили что distinct отработал у вас быстрее чем group by, который в изначальном запросе
Yii2 universal module sceleton - for basic and advanced templates
unknownby
Сообщения: 749
Зарегистрирован: 2019.11.05, 16:34
Контактная информация:

Re: GridView выбор всех данных

Сообщение unknownby »

maleks писал(а): 2021.12.16, 07:42 все, что влияет на выборку(where, group by, distinct и т.д.), естественно остается, но и тут исключения - вы же сами в своем решении выяснили что distinct отработал у вас быстрее чем group by, который в изначальном запросе
В изначальном запросе изменяется селект, остальные условия остались неизменными в запросе. И важно, что устанавливается тотал с этим запросом, а не запросом дата провайдера. Попробуйте где-нибудь на своём проекте это решение. Расскажете результат. Важно чтобы таблица с многомиллионными записями из mysql грузилась быстро. Индексы в расчёт не берём, считаем, что они правильно выставлены.
Ответить