Подвисание страницы

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Alex@
Сообщения: 568
Зарегистрирован: 2014.12.16, 09:24

Подвисание страницы

Сообщение Alex@ »

есть таблица tbl_news, в которой ~200 000 записей.
в контроллере делаю стандартные действия

Код: Выделить всё

   /**
     * Renders the index view for the module
     * @return string
     */
    public function actionIndex()
    {
        $query = News::find()->where([
            'id_category' => $this->module->id,
            'status' => $this->module->activeStatus
        ]);
        $countQuery = clone $query;
        $pages = new Pagination(['totalCount' => $countQuery->count(),'pageSize' => 15]); //
        $pages->pageSizeParam = false;
        $models = $query->offset($pages->offset)
            ->orderBy(['date_public' => SORT_DESC])
            ->limit($pages->limit)
            ->all();/**/
        return $this->render('index',[
            'models' => $models,
            'pages' => $pages
        ]);
    } 
при выполнении этого действия страница подвисает и не грузит данные......
в чем может быть дело????
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Подвисание страницы

Сообщение zelenin »

видимо ошибка, грузит все 200 т записей. дебажьте.
Alex@
Сообщения: 568
Зарегистрирован: 2014.12.16, 09:24

Re: Подвисание страницы

Сообщение Alex@ »

zelenin писал(а):видимо ошибка, грузит все 200 т записей. дебажьте.
Как ограничить выборку?
Последний раз редактировалось Alex@ 2016.11.25, 23:36, всего редактировалось 1 раз.
caHek2x
Сообщения: 1240
Зарегистрирован: 2016.04.12, 20:41

Re: Подвисание страницы

Сообщение caHek2x »

загляните в debug и в разделе ... короче все на скрине ...
Изображение
посмотрите какой запрос сколько у вас выполняется ...
Alex@
Сообщения: 568
Зарегистрирован: 2014.12.16, 09:24

Re: Подвисание страницы

Сообщение Alex@ »

в дебаге капец просто какой то.....

Код: Выделить всё

SELECT COUNT(*) FROM `tbl_news` WHERE (`id_category`='news') AND (`status`=1) - 39840.4 ms

Код: Выделить всё

SELECT * FROM `tbl_news` WHERE (`id_category`='news') AND (`status`=1) ORDER BY `date_public` DESC LIMIT 15 - 38008.8 ms
Аватара пользователя
wgetus
Сообщения: 9
Зарегистрирован: 2015.10.14, 13:08
Откуда: Гродно
Контактная информация:

Re: Подвисание страницы

Сообщение wgetus »

Alex@ писал(а):в дебаге капец просто какой то.....

Код: Выделить всё

SELECT COUNT(*) FROM `tbl_news` WHERE (`id_category`='news') AND (`status`=1) - 39840.4 ms

Код: Выделить всё

SELECT * FROM `tbl_news` WHERE (`id_category`='news') AND (`status`=1) ORDER BY `date_public` DESC LIMIT 15 - 38008.8 ms
1) Прокачай таблицу индексами. на 200т разница в скрости выборки уже должна будет ощутится весьма заметно
Тем блолее по запросу у тебя id_category строковое значение
Если ты еще не знаешь что такое индексы и зачем они нужы, тогда тебе сюда
http://ruhighload.com/post/%D0%A0%D0%B0 ... 0%B2+MySQL

2) localhost замени в конфие на 127.0.0.1 в подключении к БД. У тебя почему-то долго открывается соединение с БД(2 секунды), возможно dns ресолвится долго
замена на 127.0.0.1 должна помочь
caHek2x
Сообщения: 1240
Зарегистрирован: 2016.04.12, 20:41

Re: Подвисание страницы

Сообщение caHek2x »

'id_category`='news'
а не лучше ли категории вынести в отдельную таблицу ... а id_category цифровое значение ... связанное с той таблицей ... а если это вообще просто слова от балды которые вы один раз придумали и динамически ничего не добавляется то может вообще констант с цифровыми значениями хватит
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Подвисание страницы

Сообщение zelenin »

wgetus писал(а):2) localhost замени в конфие на 127.0.0.1 в подключении к БД. У тебя почему-то долго открывается соединение с БД(2 секунды), возможно dns ресолвится долго
замена на 127.0.0.1 должна помочь
на винде такое бывает
Аватара пользователя
wgetus
Сообщения: 9
Зарегистрирован: 2015.10.14, 13:08
Откуда: Гродно
Контактная информация:

Re: Подвисание страницы

Сообщение wgetus »

Ой, простите, на счет второго пунтка это к caHek2x, который любезно предоставил скрин.
И да, как советует caHek2x, стоит поработать над структурой таблицы или таблиц.
Сделать нормализацию БД. Уменьшится ее размер и увеличится производительность.
Но индексы по искомым значениям стоит добавить также, производительность выборки поднимается в разы,
особенно на громадных таблицах как в вашем случае.
Последний раз редактировалось wgetus 2016.11.26, 02:04, всего редактировалось 1 раз.
caHek2x
Сообщения: 1240
Зарегистрирован: 2016.04.12, 20:41

Re: Подвисание страницы

Сообщение caHek2x »

ну и на поля сортировки вроде помогает добавление индексов ...
wgetus писал(а):Ой, простите, на счет второгой пунтка это к caHek2x, который любезно предоставил скрин.
2ms
Аватара пользователя
wgetus
Сообщения: 9
Зарегистрирован: 2015.10.14, 13:08
Откуда: Гродно
Контактная информация:

Re: Подвисание страницы

Сообщение wgetus »

ахах, сори, это сигнал что нужно уже идти спать:)
И да, сортировка тоже быстрее работает.
Alex@
Сообщения: 568
Зарегистрирован: 2014.12.16, 09:24

Re: Подвисание страницы

Сообщение Alex@ »

Вот структура таблицы

Код: Выделить всё

CREATE TABLE IF NOT EXISTS `tbl_news` (
  `id` int(11) NOT NULL COMMENT 'ID',
  `url` varchar(255) NOT NULL DEFAULT '' COMMENT 'URL',
  `id_user` int(11) NOT NULL COMMENT 'Пользователь',
  `id_type` varchar(32) NOT NULL COMMENT 'Тип',
  `id_category` varchar(32) NOT NULL COMMENT 'Категория',
  `date_public` datetime NOT NULL COMMENT 'Дата публикации',
  `title` varchar(500) NOT NULL COMMENT 'Заголовок',
  `keywords` varchar(500) DEFAULT NULL COMMENT 'Keywords',
  `description` varchar(500) DEFAULT NULL COMMENT 'Description',
  `short_text` varchar(500) DEFAULT NULL COMMENT 'Подзаголовок',
  `text` text NOT NULL COMMENT 'Текст новости',
  `journalist_id` int(11) DEFAULT NULL COMMENT 'Журналист',
  `journalist_text` varchar(255) DEFAULT NULL COMMENT 'Журналист, указанный вручную',
  `photographer_id` int(11) DEFAULT NULL COMMENT 'Фотограф',
  `photographer_text` varchar(255) DEFAULT NULL COMMENT 'Фотограф, указанный вручную',
  `image` varchar(128) DEFAULT NULL COMMENT 'Изображение',
  `has_image` tinyint(4) NOT NULL DEFAULT '0' COMMENT 'Имеет фото',
  `image_title` varchar(164) DEFAULT NULL COMMENT 'Alt - изображения',
  `in_top` tinyint(4) NOT NULL DEFAULT '0' COMMENT 'В топе',
  `in_megatop` tinyint(4) NOT NULL DEFAULT '0' COMMENT 'В мегатопе',
  `mega_top_title` varchar(255) DEFAULT NULL COMMENT 'Текст в МегаТопе',
  `mega_top_link` varchar(255) DEFAULT NULL COMMENT 'Текст ссылки в МегаТопе',
  `in_mail` tinyint(4) NOT NULL DEFAULT '0' COMMENT 'В рассылке',
  `date_mail` date DEFAULT NULL COMMENT 'Дата рассылки',
  `int_interest` tinyint(4) NOT NULL DEFAULT '0' COMMENT 'На главную в "Интересно"',
  `count_coment` int(11) NOT NULL DEFAULT '0' COMMENT 'Кол-во коментариев',
  `count_views` int(11) NOT NULL DEFAULT '0' COMMENT 'Кол-во просмотров',
  `created_at` int(11) NOT NULL COMMENT 'Созданно',
  `updated_at` int(11) NOT NULL COMMENT 'Обновленно',
  `status` tinyint(4) NOT NULL DEFAULT '0' COMMENT 'Статус'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Список новостей';

Код: Выделить всё

ALTER TABLE `tbl_news`
  ADD PRIMARY KEY (`id`),
  ADD UNIQUE KEY `url` (`url`),
  ADD KEY `id_user` (`id_user`),
  ADD KEY `journalist_id` (`journalist_id`),
  ADD KEY `photographer_id` (`photographer_id`),
  ADD KEY `id_type` (`id_type`),
  ADD KEY `id_category` (`id_category`); 
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Подвисание страницы

Сообщение zelenin »

SELECT * FROM `tbl_news` WHERE (`id_category`='news') AND (`status`=1) ORDER BY `date_public` DESC LIMIT 15

берем запрос, выделяем все колонки по которым идет сравнение, сортировка, группировка (id_category, status, date_public), проверяем, чтобы по всем ним стояли индексы. Я вижу только один индекс, а значит остальные операции проходят не по индексу, а перебором.
Alex@
Сообщения: 568
Зарегистрирован: 2014.12.16, 09:24

Re: Подвисание страницы

Сообщение Alex@ »

zelenin писал(а):SELECT * FROM `tbl_news` WHERE (`id_category`='news') AND (`status`=1) ORDER BY `date_public` DESC LIMIT 15

берем запрос, выделяем все колонки по которым идет сравнение, сортировка, группировка (id_category, status, date_public), проверяем, чтобы по всем ним стояли индексы. Я вижу только один индекс, а значит остальные операции проходят не по индексу, а перебором.
Я решил изменить немного структуру таблицы:
id_category - integer ; key, id_type - integer ; key, date_public - integer ; key
Аватара пользователя
maleks
Сообщения: 1985
Зарегистрирован: 2012.12.26, 12:56

Re: Подвисание страницы

Сообщение maleks »

status не забудьте тоже сделать key
Yii2 universal module sceleton - for basic and advanced templates
nepob
Сообщения: 18
Зарегистрирован: 2016.02.23, 09:25

Re: Подвисание страницы

Сообщение nepob »

wgetus писал(а): Если ты еще не знаешь что такое индексы и зачем они нужы, тогда тебе сюда
http://ruhighload.com/post/%D0%A0%D0%B0 ... 0%B2+MySQL
Извините за оффтоп. Но подскажите, почему в этом случае прочитана только одна запись? Даже если эта запись была первой в индексной таблице, то как минимум нужно прочитать еще вторую запись чтобы понять, что дальше читать не стоит.

Изображение
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Подвисание страницы

Сообщение zelenin »

это как массив в php

Код: Выделить всё

$users = [
    'email1@mail.com' => ['id' => 1, 'name' => 'Tom', 'email' => 'email1@mail.com'],
    'email2@mail.com' => ['id' => 1, 'name' => 'Tamara', 'email' => 'email2@mail.com'],
    'email3@mail.com' => ['id' => 1, 'name' => 'Nick', 'email' => 'email3@mail.com'],
    'email4@mail.com' => ['id' => 1, 'name' => 'John', 'email' => 'email4@mail.com'],
    'email5@mail.com' => ['id' => 1, 'name' => 'James', 'email' => 'email5@mail.com'],
]; 
данный массив проиндексирован по полю email, и для нахождения элемента массива можно обратиться по индексу $users['email3@mail.com'].
если же мы хотим получить строку по имени, то нам придется перебрать весь массив до первого вхождения:
array_search('Nick', array_column($users, 'name'));
nepob
Сообщения: 18
Зарегистрирован: 2016.02.23, 09:25

Re: Подвисание страницы

Сообщение nepob »

Не пойму за счет чего обеспечивается прямой доступ к php-шной хэш-таблице (массиву). Она ведь точно так же хранится как обычная таблица, и при доступе к определенному элементу СИ (или ассемблер) должен пройтись по всей хэш-таблице.
И думаю что сравнение немного не точное, т.к. в хэш-таблице не может быть одинаковых ключей, а в обычной таблице - может.
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Подвисание страницы

Сообщение zelenin »

nepob писал(а):И думаю что сравнение немного не точное, т.к. в хэш-таблице не может быть одинаковых ключей, а в обычной таблице - может.
я вам ответил как новичку, но если вы имеете уже базис, и знаете что такое хэш-таблица, то вам надо в гугл для более компетентного описания, а не по форумам шарить.
https://en.wikipedia.org/wiki/B-tree
Restlin
Сообщения: 139
Зарегистрирован: 2011.09.09, 18:12

Re: Подвисание страницы

Сообщение Restlin »

С mysql не работал, но на примере mssql и postgreSQL субд хранит статистику распределения значений в индексируемой колонке. Иначе говоря СУБД знает, что такое значение в колонке email встречается только раз. Не говоря уже о всяких дополнительных не ANSI фишках индексов типа unique.
Ответить