Вы не вошли.
В принципе тут все что можно учтено при таком подходе.
1. Хочешь сам задавай ID категорий, тогда сам логически подбирай какие категории можно смешивать, чтобы смысл был.
2. В новости можешь оставить поиск по всем категориям, которые в новости, если на сайте логически это допустимо и нужно.
3. Хочешь учитывай только первую категорию, если поиск по всем не подходит.
Вроде все варианты из реального использования. Тогда приведу к этому виду плагин, а там если будут какие новые идеи или необычные примеры использования, то будем обсуждать.
Вне форума
Небольшое сравнение возможно нового алгоритма работы в сравнении с прошлым.
Дано:
таблица _news - 82322 записи, 180 Mb
таблица _news_map - 172668 записи, 1.5 Mb
Старый запрос.
SELECT SQL_NO_CACHE *
FROM 2z_news
WHERE (
(
catid
REGEXP '[[:<:]](16)[[:>:]]'
)
OR (
catid
REGEXP '[[:<:]](8)[[:>:]]'
)
)
ORDER BY postdate DESC
LIMIT 0 , 30Время выполнения: 0.0022 сек в среднем
Если сделать ORDER BY views то 0.0050 с
Переделанный запрос.
SELECT SQL_NO_CACHE nm . * , n . *
FROM 2z_news_map nm
LEFT JOIN 2z_news n ON n.id = nm.newsID
WHERE nm.categoryID =16
OR nm.categoryID =8
LIMIT 0 , 30Время выполнения: 0.0037 сек в среднем
На 0.001 запрос с JOIN использующий индексы выполняется хуже, чем полный перебор всей таблицей с REGXP.
Если добавить ORDER BY n.postdate DESC (или views) в переделанный запрос, то выполнение вырастает до 0.3 сек. !!!
Ситуация меняется, если ставить LIMIT 0, 2000 например. Тогда у REGXP - 0.1630 сек, против 0.0784 сек. Выигрыш в два раза. Но такие объемы никому не нужны ясное дело.
Две проблемы:
1. Почему полный скан оказывается быстрее. Думаю из-за того, что мы быстро получаем необходимые 30 записей. Но непонятно это так совпало для этих категорий и какая вообще будет тенденция для универсального решения? Пока от JOIN'а не в восторге. Но возможно при других категориях он выдаст более интересные результаты и можно будет пожертвовать разницей в 0.001 с Посмотрел для категории с ID = 5, теперь REGXP проигрывает 0.0065 против 0.0019. Новости все эти не очень близко к началу.
2. Главный. Почему при JOIN'e при добавлении ORDER BY n.postdate DESC все накрывается медным тазом и начинает дико тормозить по 0.3 с?
Вне форума
Wolverine, на первой странице у тебя действительно первый запрос отработает быстро, т.к. новостей в данной категории - много.
А ты попробуй:
1. limit 20000, 30 и посмотри что будет
2. сделать запрос по категории, в которой вообще нет новостей или их очень мало (к примеру, были в самом начале таблицы)
Вне форума
Что там с поддержкой xfields'a? Актуально как никогда. :/
Отредактировано infinity237 (2012-01-16 22:26:57)
Вне форума
vitaly
у меня всегда будет 0, N, где N - обычно не больше 10-20 для отсортированной по просмотрам, комментариям или дате таблице.
ОК, по первому пункту можно заменить regxp на join. Если решится пункт 2.
Я вот не пойму откуда такая задержка при попытке сортировки. Можно как-то посмотреть этапы выполнения запроса и длительность каждого этапа? Типа сначала ищем в news_map за 0.1, потом делаем join, потом сортировку, чтобы понять где проблема появляется.
Вне форума
Wolverine, поставь перед запросом ключевое слово explain и mySQL тебе покажет как он этот запрос собирается исполнять.
Причина задержки проста:
* при выборке напрямую из news у нас есть ключи по которым ты делаешь сортировку. в итоге - идёт полный перебор данных (уже проиндексированных), но данные у тебя находятся очень быстро (т.к. нужных тебе новостей довольно много среди последних новостей)
* при выборке через news_map сначала выбираются ID'шники всех новостей данной категории, потом выполняется join и делается сортировка
В твоей ситуации (для top_news) первый запрос должен работать быстрее.
Вне форума
vitaly, explain смотрел. Но он не совсем полный, то есть не говорит в какой последовательности и что делает.
Для REGXP используется ключ news_postdate.
При таком запросе
EXPLAIN SELECT id, alt_name, postdate, title, views, com, catid, rating, votes
FROM 2z_news
WHERE approve =1
AND postdate >=1325924040
AND (
(
catid
REGEXP '[[:<:]](2)[[:>:]]'
)
OR (
catid
REGEXP '[[:<:]](8)[[:>:]]'
)
)
ORDER BY views DESC
LIMIT 0 , 10тоже news_postdate. По views индекс не используется почему-то.
Если через news_map, то сначала индекс по categoryID, затем в таблице news индекс по PRIMARY, id новости. Индекс по postdate уже не используется. Но самое стремное, что появляется Using temporary; при добавлении ORDER BY, отсюда видимо и лаги.
В общем оставляю вариант с REGXP.
Спасибо.
Вне форума
Wolverine, "use temporary" используется для сортировки (если данные не берутся через нужный индекс).
В этом нет ничего страшного, всё зависит от размера выборки.
Относительно используемых ключей/индексов - mySQL можно заставить использовать конкретный индекс.
Но в твоём запросе я с ним полностью согласен - правильнее выборку делать по postdate, а не по views.
Вне форума
vitaly, а использоваться может только один индекс? Поможет ли создание для такого случая индекса по двум полям postdate, views? Мне по хорошему, чтобы покрыть все варианты нужно еще добавить индекс по postdate, com. Для самых комментируемых и просматриваемых за N дней.
Вне форума
Итого у меня какие варианты. Отбор верхних записей.
1. Сортировка только по postdate. Для него есть индекс по умолчанию в движке.
2. Сортировка только по views. Для него есть индекс по умолчанию в движке.
3. Сортировка только по com. Для него индекса нет. Кто его должен создать? Я при установке top_news или сам плагин comments? Сейчас идет полный перебор.
4. Произвольный отбор ORDER BY RAND(). Тут ничего не поделаешь. Надо заменять его http://hudson.su/2010/09/16/mysql-optim … r-by-rand/
5. Отбор за последние N дней по postdate. Для него есть индекс по умолчанию в движке.
6. Отбор за последние N дней по views. Для него есть индекс по умолчанию в движке. Используется только postdate. Имеет ли смысл создавать индекс по двум полям postdate, views?
7. Отбор за последние N дней по com. Для него есть индекс по умолчанию в движке. Используется только postdate. Имеет ли смысл создавать индекс по двум полям postdate, com?
Вне форума
Wolverine, использоваться может только один индекс.
Но никто не мешает ему быть составным.
Плагину ничего не мешает создавать свои индексы при установке. Но, естественно, их надо делать с умом (и удалять при удалении плагина).
Вне форума
Wolverine, можешь научить плагин понимать bb media ?
Вне форума
Я в процессе поиска решения, которое не будет требовать от меня модификации плагина для ручной подгонки под каждый плагин отдельно. Иначе не top_news получится, а сбор кода со всех новостных плагинов
В идеале в настройках выводить список новостных плагинов, с которыми необходимо интегрироваться, отмечать их галочками и все. Точнее решение я нашел, но в связи с экзаменом на неделе мне пока не удаётся его опробовать.
Вне форума
Можно ли как-нибудь исключать из top_news блоков новость на которой находится конкретный пользователь?
Вне форума
infinity237, legenda, это все индивидуально. Какая задача? Потому что в каких-то вариантах придется забыть о кэшировании, если блок будет настолько динамический. Но в каких-то вариантах, может быть устроить кэш минус эта новость.
Вне форума
Лично мне надо вывести топ_5 последних новостей из 2 категорий. Если в топ попадает новость, которая открыта, то не показывать её - вместо неё другую по времени.
Вне форума
Лично мне надо вывести топ_5 последних новостей из 2 категорий. Если в топ попадает новость, которая открыта, то не показывать её - вместо неё другую по времени.
а что такое топ_5 последних новостей это топ по просмотрах или это просто последние?
лично я думаю что такой вариант нужен для блока который стоит в новости и который выводит последние новости, или темболее последние новости из своей категории, так как топ по просмотам и топ по комментах как правило ставлят или в категории или на главной, а для случайных там особо нету разныцы они же случайные :)
Отредактировано legenda (2012-01-21 18:03:41)
Вне форума
а что такое топ_5 последних новостей это топ по просмотрах или это просто последние?
Просто последние.
Вне форума
В варианте последних новостей можно просто изначально запрашивать на 1 новость больше, хранить полученные данные отдельно и каждый раз смотреть попадет ли эта новость туда или нет. Если нет, то берем 6 - 1 новость и выводим их.
+: кэш остается, но каждый раз рендерится шаблон, так как его содержимое разное
Вне форума
Да, такое решение подойдет.
Вне форума
В варианте последних новостей можно просто изначально запрашивать на 1 новость больше, хранить полученные данные отдельно и каждый раз смотреть попадет ли эта новость туда или нет. Если нет, то берем 6 - 1 новость и выводим их.
+: кэш остается, но каждый раз рендерится шаблон, так как его содержимое разное
в варианте большого количества блоков эта штука будет сильно напрягать сайт?
Вне форума
[ Сгенерировано за 0.024 сек, 7 запросов выполнено - Использовано памяти: 629.86 Кбайт (Пик: 682.86 Кбайт) ]