Mister_Black

Рейтинг
183
Регистрация
24.02.2009

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


<?php function show_previous_posts_from_category ($the_post_id, $the_category_id = 0, $post_num) {
$num = 0;
global $wpdb;
$sql = "SELECT p.ID, post_date, post_content, post_title, post_name
FROM $wpdb->posts p
WHERE 1=1 AND (p.ID IN(
SELECT object_id
FROM $wpdb->term_relationships
WHERE term_taxonomy_id = '$the_category_id'
))
AND p.ID < '$the_post_id'
ORDER BY p.ID DESC
LIMIT $post_num";
$result = $wpdb->get_results($sql, OBJECT);
global $post;
foreach ($result as $post) {
setup_postdata($post);
?>
<div class="related"><a href="<?php the_permalink() ?>" title="<?php the_title(); ?>"><img src="<?php echo catch_that_image() ?>" alt="<?php the_title(); ?>" height="115" width="150"></a><b><?php the_title(); ?></b></div>
<?php
$num++;
}
if ( $num < $post_num || !$result ) {
$need_more = $post_num-$num;
$sql = "SELECT p.ID, post_date, post_content, post_title, post_name
FROM $wpdb->posts p
WHERE 1=1 AND (p.ID IN(
SELECT object_id
FROM $wpdb->term_relationships
WHERE term_taxonomy_id = '$the_category_id'
))
AND p.ID > '$the_post_id'
ORDER BY p.ID DESC
LIMIT $need_more";
$more_posts = $wpdb->get_results($sql, OBJECT);
foreach ($more_posts as $post){
setup_postdata($post);
?>
<div class="related"><a href="<?php the_permalink() ?>" title="<?php the_title(); ?>"><img src="<?php echo catch_that_image() ?>" alt="<?php the_title(); ?>" height="115" width="150"></a><b><?php the_title(); ?></b></div>
<?php }}} ?>
<?php $the_cat = get_the_category(); $the_cat_id = $the_cat[0]->term_taxonomy_id; show_previous_posts_from_category($post->ID, $the_cat_id, 4); wp_reset_query(); ?>

я тут переписал немного запрос

SELECT SQL_NO_CACHE p.ID, post_date, post_content, post_title, post_name

FROM wp_posts p

WHERE 1=1 AND ( p.ID IN (

SELECT object_id

FROM wp_term_relationships

WHERE term_taxonomy_id IN ('9')

) )

AND p.ID < '2756199'

ORDER BY p.ID DESC

LIMIT 4

запрос занял 0.0005 сек

id select_type table type possible_keys key key_len ref rows Extra

1 PRIMARY p range PRIMARY PRIMARY 3 NULL 328324 Using where

2 DEPENDENT SUBQUERY wp_term_relationships unique_subquery PRIMARY,term_taxonomy_id PRIMARY 5 func,const 1 Using index; Using where

единственное, что потерялась кольцевая перелинковка, то есть когда доходит до первого поста категории, раньше показывало последние посты, теперь для первых постов нет ссылок, вот думаю, что я упустил?

netwind:
Mister_Black, настройки нормальные. Что вы к ним прикопались ?
Тут нужно погружение в этот плагин. Разобраться, что там за данные. Доступ к ним для экспериментов. Выяснить на какие компромиссы вы готовы пойти. Все обсуждать и согласовывать с вами. Кто это все спонсировать будет ?

Выключите эту навигацию. Или в гугле найдите похожий проблемный запрос и методы решения. Все же это WP и проблемы с ним редко бывают уникальными. (Я, однако, не нашел ) .


А это полезный совет от mysqltuner. Стоит включить с порогом в районе 1 секунды чтобы определять запросы, на которые нужно обратить внимание в первую очередь.

like ещё притормаживает иногда, но я это решил ограничив поиск то title, если отключить скрипт предыдущих постов из категории, то всё летает, а при включенном тормозит и растёт нагрузка, может есть смысл разбить его на 2 запроса, чтобы один запрос делал выборку по id, а второй запрос уже брал остальную информацию из выделенных по id записей в данном случае 4 записи, у меня по такому принципу сделана выборка категорий, один запрос берёт id ограниченные 10 постами на странице, а второй запрос вытягивает остальное уже из этих 10 не перетряхивая все посты в категории, раньше тоже жутко тормозило, вроде эту проблему решили аж только в 4 версии WP, она возникала на блогах с большим количеством постов, более 10к.

Надо подумать как теперь этот метод использовать в этом скрипте.

Оптимизайка:
Все равно многовато. Теперь еще LEFT JOIN -> INNER JOIN сделайте и покажите план выполнения.

c order by

запрос занял 3.9776 сек

SQL-запрос: EXPLAIN SELECT SQL_NO_CACHE wposts . * FROM wp_posts wposts INNER JOIN wp_term_relationships ON ( wposts.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 wp_term_taxonomy.taxonomy = 'category' AND wp_term_taxonomy.term_id = '49' AND wposts.post_status = 'publish' AND wposts.post_type = 'post' AND wposts.ID < '2756199' ORDER BY wposts.ID DESC LIMIT 4;

Строки: 3

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 79416 Using where

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

без order by

запрос занял 0.0034 сек

SQL-запрос: EXPLAIN SELECT SQL_NO_CACHE wposts . * FROM wp_posts wposts INNER JOIN wp_term_relationships ON ( wposts.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 wp_term_taxonomy.taxonomy = 'category' AND wp_term_taxonomy.term_id = '49' AND wposts.post_status = 'publish' AND wposts.post_type = 'post' AND wposts.ID < '2756199' LIMIT 4;

Строки: 3

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_term_relationships ref PRIMARY,term_taxonomy_id term_taxonomy_id 2 const 79416 Using where

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

вывод из mysqltuner

-------- General Statistics --------------------------------------------------

[--] Skipped version check for MySQLTuner script

[OK] Currently running supported MySQL version 5.1.71

[OK] Operating on 64-bit architecture

-------- Storage Engine Statistics -------------------------------------------

[--] Status: -Archive -BDB -Federated -InnoDB -ISAM -NDBCluster

[--] Data in MyISAM tables: 688M (Tables: 20)

[!!] Total fragmented tables: 1

-------- Performance Metrics -------------------------------------------------

[--] Up for: 18h 23m 57s (780K q [11.782 qps], 56K conn, TX: 6B, RX: 168M)

[--] Reads / Writes: 54% / 46%

[--] Total buffers: 144.0M global + 17.2M per thread (100 max threads)

[OK] Maximum possible memory usage: 1.8G (21% of installed RAM)

[OK] Slow queries: 0% (1/780K)

[OK] Highest usage of available connections: 19% (19/100)

[OK] Key buffer size / total MyISAM indexes: 64.0M/40.5M

[OK] Key buffer hit rate: 99.9% (476M cached / 435K reads)

[OK] Query cache efficiency: 73.1% (361K cached / 494K selects)

[!!] Query cache prunes per day: 15565

[OK] Sorts requiring temporary tables: 1% (1K temp sorts / 82K sorts)

[OK] Temporary tables created on disk: 5% (2K on disk / 40K total)

[OK] Thread cache hit rate: 99% (19 created / 56K connections)

[!!] Table cache hit rate: 15% (61 open / 389 opened)

[OK] Open file limit used: 0% (90/24K)

[OK] Table locks acquired immediately: 99% (365K immediate / 365K locks)

-------- Recommendations -----------------------------------------------------

General recommendations:

Run OPTIMIZE TABLE to defragment tables for better performance

MySQL started within last 24 hours - recommendations may be inaccurate

Enable the slow query log to troubleshoot bad queries

Increase table_cache gradually to avoid file descriptor limits

Variables to adjust:

query_cache_size (> 64M)

table_cache (> 512)

из tuning-primer

-- MYSQL PERFORMANCE TUNING PRIMER --

- By: Matthew Montgomery -

MySQL Version 5.1.71 amd64

Uptime = 0 days 18 hrs 28 min 0 sec

Avg. qps = 11

Total Questions = 782585

Threads Connected = 2

Warning: Server has not been running for at least 48hrs.

It may not be safe to use these recommendations

To find out more information on how each of these

runtime variables effects performance visit:

http://dev.mysql.com/doc/refman/5.1/en/server-system-variables.html

Visit http://www.mysql.com/products/enterprise/advisors.html

for info about MySQL's Enterprise Monitoring and Advisory Service

SLOW QUERIES

The slow query log is NOT enabled.

Current long_query_time = 10.000000 sec.

You have 1 out of 782606 that take longer than 10.000000 sec. to complete

Your long_query_time seems to be fine

BINARY UPDATE LOG

The binary update log is NOT enabled.

You will not be able to do point in time recovery

See http://dev.mysql.com/doc/refman/5.1/en/point-in-time-recovery.html

WORKER THREADS

Current thread_cache_size = 16

Current threads_cached = 15

Current threads_per_sec = 0

Historic threads_per_sec = 0

Your thread_cache_size is fine

MAX CONNECTIONS

Current max_connections = 100

Current threads_connected = 2

Historic max_used_connections = 19

The number of used connections is 19% of the configured maximum.

Your max_connections variable seems to be fine.

No InnoDB Support Enabled!

MEMORY USAGE

Max Memory Ever Allocated : 455 M

Configured Max Per-thread Buffers : 1.68 G

Configured Max Global Buffers : 128 M

Configured Max Memory Limit : 1.80 G

Physical Memory : 8.49 G

Max memory limit seem to be within acceptable norms

KEY BUFFER

Current MyISAM index space = 40 M

Current key_buffer_size = 64 M

Key cache miss rate is 1 : 1094

Key buffer free ratio = 52 %

Your key_buffer_size seems to be fine

QUERY CACHE

Query cache is enabled

Current query_cache_size = 64 M

Current query_cache_used = 53 M

Current query_cache_limit = 1 M

Current Query cache Memory fill ratio = 83.69 %

Current query_cache_min_res_unit = 4 K

However, 11933 queries have been removed from the query cache due to lack of memory

Perhaps you should raise query_cache_size

MySQL won't cache query results that are larger than query_cache_limit in size

SORT OPERATIONS

Current sort_buffer_size = 6 M

Current read_rnd_buffer_size = 6 M

Sort buffer seems to be fine

JOINS

Current join_buffer_size = 1.00 M

You have had 0 queries where a join could not use an index properly

Your joins seem to be using indexes properly

OPEN FILES LIMIT

Current open_files_limit = 24576 files

The open_files_limit should typically be set to at least 2x-3x

that of table_cache if you have heavy MyISAM usage.

Your open_files_limit value seems to be fine

TABLE CACHE

Current table_open_cache = 512 tables

Current table_definition_cache = 256 tables

You have a total of 20 tables

You have 61 open tables.

The table_cache value seems to be fine

TEMP TABLES

Current max_heap_table_size = 16 M

Current tmp_table_size = 16 M

Of 38901 temp tables, 5% were created on disk

Created disk tmp tables ratio seems fine

TABLE SCANS

Current read_buffer_size = 4 M

Current table scan ratio = 58007 : 1

read_buffer_size seems to be fine

TABLE LOCKING

Current Lock Wait ratio = 1 : 555

You may benefit from selective use of InnoDB.

память Physical Memory : 8.49 G показывает общую серверную, на впс выделено 2гб

vandamme:
Кеширование по времени создать не вариант? Запрос срабатывает при каждом обращении к странице?

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

вот сам скрипт который вызывает этот запрос:

<?php function show_previous_posts_from_category ($the_post_id, $the_category_id = 0, $post_num) {

$num = 0;
global $wpdb;
$sql = "SELECT wposts.*
FROM $wpdb->posts wposts IGNORE INDEX (PRIMARY,type_status_id_date)
LEFT JOIN $wpdb->term_relationships ON (wposts.ID = $wpdb->term_relationships.object_id)
LEFT JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)
WHERE $wpdb->term_taxonomy.taxonomy = 'category'
AND $wpdb->term_taxonomy.term_id = '$the_category_id'
AND wposts.post_status = 'publish'
AND wposts.post_type = 'post'
AND wposts.ID < '$the_post_id'
ORDER BY wposts.ID DESC
LIMIT $post_num";
$result = $wpdb->get_results($sql, OBJECT);
global $post;
foreach ($result as $post) {
setup_postdata($post);
?>
<div class="related"><a href="<?php the_permalink() ?>" title="<?php the_title(); ?>"><img src="<?php echo catch_that_image() ?>" alt="<?php the_title(); ?>" height="115" width="150"></a><b><?php the_title(); ?></b></div>
<?php
$num++;
}
if ( $num < $post_num || !$result ){ $need_more = $post_num-$num;
$more_posts = get_posts("numberposts=$need_more&category=$the_category_id");
foreach ($more_posts as $post){ setup_postdata($post);
?>
<div class="related"><a href="<?php the_permalink() ?>" title="<?php the_title(); ?>"><img src="<?php echo catch_that_image() ?>" alt="<?php the_title(); ?>" height="115" width="150"></a><b><?php the_title(); ?></b></div>
<?php }}} ?>
<?php $the_cat = get_the_category(); $the_cat_id = $the_cat[0]->cat_ID; show_previous_posts_from_category($post->ID, $the_cat_id, 4); wp_reset_query(); ?>
Оптимизайка:
А если убрать ORDER BY, сильно изменится время выполнения? Если да, то крутите sort_buffer_size или думайте над размещением временных файлов для сортировки на SSD.

запрос занял 0.0214 сек.

SELECT SQL_NO_CACHE wposts. *

FROM wp_posts wposts

LEFT JOIN wp_term_relationships ON ( wposts.ID = wp_term_relationships.object_id )

LEFT JOIN wp_term_taxonomy ON ( wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id )

WHERE wp_term_taxonomy.taxonomy = 'category'

AND wp_term_taxonomy.term_id = '49'

AND wposts.post_status = 'publish'

AND wposts.post_type = 'post'

AND wposts.ID < '2756199'

LIMIT 4

попробую sort_buffer_size поднять, SSD для меня не вариант, на моей впске нет такой возможности, переходить на дедик из за 1 запроса тоже как то не хочется.

netwind:
Ничего.
Mysql не сломан. Вы не в том направлении думаете. Mysql делает работу по считыванию и объединению данных, которую вы ему задали.
Вам нужно изменить запрос.

А что изменить в запросе?

Пробовал менять на inner join не сильно помогло,

всего в таблице wp_posts 340000 записей, если включать для неё индексы, начинает жутко тормозить, если игнорить индексы для этой таблицы, то это даёт существенный прирост скорости, но считывание идёт по всем полям, то есть для каждой категории по всем 340000 записям, основные тормоза из за категории в которой 70000 записей.

запрос занял 3.3663 сек

SQL-запрос: EXPLAIN SELECT SQL_NO_CACHE wposts . * FROM wp_posts wposts LEFT JOIN wp_term_relationships ON ( wposts.ID = wp_term_relationships.object_id ) LEFT JOIN wp_term_taxonomy ON ( wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id ) WHERE wp_term_taxonomy.taxonomy = 'category' AND wp_term_taxonomy.term_id = '49' AND wposts.post_status = 'publish' AND wposts.post_type = 'post' AND wposts.ID < '2756199' ORDER BY wposts.ID DESC LIMIT 4;

Строки: 3

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 77350 Using where

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

запрос занял 0.5007 сек.

SQL-запрос: EXPLAIN SELECT SQL_NO_CACHE wposts . * FROM wp_posts wposts IGNORE INDEX (PRIMARY,type_status_id_date) LEFT JOIN wp_term_relationships ON ( wposts.ID = wp_term_relationships.object_id ) LEFT JOIN wp_term_taxonomy ON ( wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id ) WHERE wp_term_taxonomy.taxonomy = 'category' AND wp_term_taxonomy.term_id = '49' AND wposts.post_status = 'publish' AND wposts.post_type = 'post' AND wposts.ID < '2756199' ORDER BY wposts.ID DESC LIMIT 4;

Строки: 3

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 filesort

1 SIMPLE wposts ALL NULL NULL NULL NULL 337241 Using where

1 SIMPLE wp_term_relationships eq_ref PRIMARY,term_taxonomy_id PRIMARY 5 site.wposts.ID,const 1 Using where; Using index

по своему опыту скажу, что canonical ухудшает попадание в индекс новых постов, я его в начале марта поставил у себя на блоге с тех пор в индекс попало только 3 новых поста, короче какая то муть с canonical'om

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

Ап!

Подскажите пожалуйста, может rel=canonical замедлить индексацию?

очень туго стал попадать новый контент в индекс.

У меня такая же фигня, с начала марта в индекс гугла ничего не добавляется, тоже не пойму в чём проблема.

Всего: 713