Как избавиться от временных таблиц

12
MB
На сайте с 24.02.2009
Offline
182
1431

Всем привет!

Есть VDS, на нём большой блог на вордпресс, разрослась одна категория до 70000 постов и вот из за неё получился головняк с временными таблицами.

вот сам запрос, думаю известный достаточно запрос

SELECT SQL_NO_CACHE wp_posts.ID
FROM wp_posts
INNER JOIN wp_term_relationships ON ( wp_posts.ID = wp_term_relationships.object_id )
INNER JOIN wp_term_taxonomy ON ( wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id )
WHERE 1 =1
AND wp_term_taxonomy.taxonomy = 'category'
AND wp_term_taxonomy.term_id
IN (
'49'
)
AND wp_posts.post_type = 'post'
AND (
wp_posts.post_status = 'publish'
)
GROUP BY wp_posts.ID
ORDER BY wp_posts.post_date DESC
LIMIT 190 , 10

время выполнения - запрос занял 0.4974 сек.

explain

id select_type table type possible_keys key key_len ref rows Extra

1 SIMPLE wp_term_taxonomy const PRIMARY,term_id_taxonomy,taxonomy term_id_taxonomy 44 const,const 1 Using temporary; Using filesort

1 SIMPLE wp_term_relationships ref PRIMARY,term_taxonomy_id term_taxonomy_id 2 const 69912

1 SIMPLE wp_posts eq_ref PRIMARY,type_status_id_date PRIMARY 3 site.wp_term_relationships.object_id 1 Using where

Vin_cent
На сайте с 22.01.2010
Offline
171
#1

Если временные таблицы создаются в памяти, а не на диске, то в чём собственно проблема?

N
На сайте с 06.05.2007
Offline
419
#2
Есть VDS, на нём большой блог на вордпресс, разрослась одна категория до 70000 постов

вот сам запрос, думаю известный достаточно запрос

Смотря кому известный. Обычный блог для людей, который ведут люди в один момент не напишет 70000 постов и уж точно постарается улучшить и таксономию и вообще ресурсы к тому моменту когда он разрастется . Разработчики wordpress на это не рассчитывают. Они знают, что у вас сеошная помойка, презирают и делать ничего не будут.

Я бы попытался вытащить фильтр таксономии "наверх" и тогда основная выборка будет цепляться за индекс type_status_date. По крайней мере у меня цепляется, но где я возьму столько мусора в блоге?

Попробуйте у себя план и скорость вот на таком фокусе:


select wpint.id from(
SELECT wp_posts.ID, wp_term_taxonomy.term_id
FROM wp_posts
INNER JOIN wp_term_relationships ON ( wp_posts.ID = wp_term_relationships.object_id )
INNER JOIN wp_term_taxonomy ON ( wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id )
WHERE 1 =1
AND wp_term_taxonomy.taxonomy = 'category'
AND wp_posts.post_type = 'post'
AND (
wp_posts.post_status = 'publish'
)
GROUP BY wp_posts.ID
having wp_term_taxonomy.term_id in ('49')
ORDER BY wp_posts.post_date DESC
LIMIT 190 , 10 ) wpint


Но без экспериментальных данных ничего об выгоде и даже правильности этого запроса не скажешь. Кроме того, нужно же еще заставить wordpress собрать из кусочков именно такого вида запрос.

Вероятно, при этом листинг других категорий ухудшится. Может, собирать два вида запроса в зависимости от категории.

Формально запрос не избавляет от временной таблицы, но объем данных в ней сократится.

В целом, понятно почему кеширование так популярно. С этим просто ничего другого не сделать.

Vin_cent:
Если временные таблицы создаются в памяти, а не на диске, то в чём собственно проблема?

Скорее всего на диске.

Кнопка вызова админа ()
MB
На сайте с 24.02.2009
Offline
182
#3

Спасибо за советы, попробую эту категорию разделить на несколько, типа "название категории - архив за 2013г", "название категории - архив за 2014г"

надо только с запросом разобраться с помощью которого такое можно сделать,

вобщем я в этом не силён надо профи искать для того чтобы разбить категорию на несколько.

до 20000 постов в категории отрабатываются сервером нормально 0.02сек примерно, а вот всё что выше видимо лезет на диск и в результате тормоза.

Vin_cent
На сайте с 22.01.2010
Offline
171
#4

Не надо тебе лезть в движок вордпресса. Просто настрой mysql, пример:

1. Создай виртуальный диск в памяти:

#shell> mkdir -p /mnt/ramdisk

#shell> chown mysql:mysql /mnt/ramdisk

#shell> mount -t tmpfs -o size=1024M tmpfs /mnt/ramdisk

2. Пропиши в конфиге mysql (/etc/my.cnf):

tmpdir=/mnt/ramdisk

3. service mysqld restart

Это всё.

N
На сайте с 06.05.2007
Offline
419
#5
Vin_cent:
Это всё.

Это все, что обычно могут предложить.

Но такие временные таблицы в плане- в любом случае плохой показатель. Хоть на диске, хоть в tmpfs. Хорошо бы от них совсем избавиться.

Использовать tmpfs для tmpdir, конечно, стоит, если еще не используется.

Vin_cent
На сайте с 22.01.2010
Offline
171
#6
netwind:
Это все, что обычно могут предложить.
Но такие временные таблицы в плане- в любом случае плохой показатель. Хоть на диске, хоть в tmpfs. Хорошо бы от них совсем избавиться.
Использовать tmpfs для tmpdir, конечно, стоит, если еще не используется.

Тебе же написали, Wordpress. Что ты предлагаешь, ковыряться там? Смысл тогда в wordpress'e?

N
На сайте с 06.05.2007
Offline
419
#7

Vin_cent, ну если есть запрос и его план, значит ТС хотел именно поковыряться. Не зависимо от мнения безруких сеонизаторов и сложившихся из-за них традиций в отрасли.

MB
На сайте с 24.02.2009
Offline
182
#8

Вобщем запрос вот так сделал

EXPLAIN SELECT SQL_NO_CACHE wp_posts.ID
FROM wp_posts
USE INDEX ( date_id )
INNER JOIN wp_term_relationships ON ( wp_posts.ID = wp_term_relationships.object_id )
INNER JOIN wp_term_taxonomy ON ( wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id )
WHERE 1 =1
AND wp_term_taxonomy.taxonomy = 'category'
AND wp_term_taxonomy.term_id
IN (
'49'
)
ORDER BY wp_posts.post_date DESC
LIMIT 10140 , 10

запрос занял 0.0551 сек (вполне приемлемо)

id select_type table type possible_keys key key_len ref rows Extra

1 SIMPLE wp_term_taxonomy const PRIMARY,term_id_taxonomy,taxonomy term_id_taxonomy 44 const,const 1

1 SIMPLE wp_posts index NULL date_id 11 NULL 10150 Using index

1 SIMPLE wp_term_relationships eq_ref PRIMARY,term_taxonomy_id PRIMARY 5 site.wp_posts.ID,const 1 Using index

и никаких темпорари

но остался вопрос, как теперь этот запрос внедрить в выборку категории

надо что то типа?

function sql($wp_query){

if (is_category()){

$wp_query->sql('sql');}}

add_filter('pre_get_posts','sql');

насколько я знаю с помощью pre_get_posts можно изменить только хвост запроса

Vin_cent, на моём вдс к сожалению ramdisk не сделать

Vin_cent
На сайте с 22.01.2010
Offline
171
#9
Mister_Black:
Вобщем запрос вот так сделал


запрос занял 0.0551 сек (вполне приемлемо)
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE wp_term_taxonomy const PRIMARY,term_id_taxonomy,taxonomy term_id_taxonomy 44 const,const 1
1 SIMPLE wp_posts index NULL date_id 11 NULL 10150 Using index
1 SIMPLE wp_term_relationships eq_ref PRIMARY,term_taxonomy_id PRIMARY 5 site.wp_posts.ID,const 1 Using index
и никаких темпорари

но остался вопрос, как теперь этот запрос внедрить в выборку категории
надо что то типа?
function sql($wp_query){
if (is_category()){
$wp_query->sql('sql');}}
add_filter('pre_get_posts','sql');

насколько я знаю с помощью pre_get_posts можно изменить только хвост запроса

Vin_cent, на моём вдс к сожалению ramdisk не сделать

А когда выйдет очередное обновление wordpress, опять пойдёшь искать-править-код там? Допиливать wordpress, имхо, глупая затея.

MB
На сайте с 24.02.2009
Offline
182
#10
Vin_cent:
А когда выйдет очередное обновление wordpress, опять пойдёшь искать-править-код там? Допиливать wordpress, имхо, глупая затея.

я его и не обновляю, у меня по сути это уже и не вордпресс, там 70% кода переписано, если бы у меня стоял вордпресс не кастомизированный, этот сайт с 300000 постов на впске даже не запустился, с морды всего 5 запросов на базу, в то время как у неоптимизированного вордпресса от 20 и выше, к тому же я не использую html кеш, потому как динамика на страницах нужна.

вобщем осталось только два проблемных запроса этот и like, скорее всего fulltext придётся делать.

12

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий