Появились медленные запросы mysql.

iccup
На сайте с 01.05.2016
Offline
195
1400

База данных сайта разрослась, около 1 Гб. Сайт на dle 11.2. Посещаемость небольшая около 3 к сутки. В логе медленных запросов такая штука -

# Time: 180806 12:20:56
# User@Host: User[User] @ localhost []
# Query_time: 6.499257 Lock_time: 0.000030 Rows_sent: 1 Rows_examined: 1471843
SET timestamp=1533547256;
SELECT COUNT(*) as count FROM dle_post WHERE approve=1 AND allow_main=1;

Это обращение к главной странице, там ничего особенного, просто список постов отсортированных по дате.

<!-- Время затраченное на выполнение MySQL запросов: 6,50198 секунд -->
Страницы новостей открываются значительно быстрее. Вот не пойму в чем может быть проблема. Где какие настройки поменять. В my.cnf
[mysqld]
collation-server = utf8_general_ci
character-set-server = utf8
local-infile=0
innodb_file_per_table = 1
pid-file = /var/run/mysqld/mysqld.pid
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
bind-address = 127.0.0.1
max_allowed_packet = 128M
log-slow-queries=/tmp/slow_queries.log
long_query_time=5

[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

Сам сервер - KS-11 Server - Intel W3520 - 16GB DDR3 ECC 1333 MHz - SoftRaid 2x2To SATA

kimsufi.com ( https://www.kimsufi.com ) очень дешевые и качественные дедики https://clck.ru/gvF9p - антибот, использую уже 3 года.
Evas EvaSystems
На сайте с 31.05.2012
Offline
104
#1

Вам необходимо грамотно настроить ваш сервер, как минимум mysql точно.

Стандартные настройки хорошо, но они не подходят для реальных задач.

mysqltuner вам в помощь, но делайте всё с умом, не надо ставить огромные значения,

также как и не всегда стоит слепо следовать рекомендациям тюннера.

Далее ваш SELECT затронул 1.4млн строк, это не есть хорошо.

Проверьте его через EXPLAIN, убедитесь чтобы запрос использовал индексы.

Если индексов в базе нет, то обязательно добавьте их где не хватает.

Точно так-же и с остальными медленными запросами.

Системный администратор Linux. Настройка, сопровождение и оптимизация серверов. Отзывы - searchengines.guru/ru/forum/1017473
danforth
На сайте с 18.12.2015
Offline
153
#2

Индекс тут бессмысленный, т.к. approve и allow_main скорее всего флаги, кардиналити у них будет очень низкий.

Ваш вариант - кешировать данные, или если точность не кретична - ходить в информационные таблицы.

Junior Web Developer
_
На сайте с 24.03.2008
Offline
381
#3

А еще лучше выкинуть этот count вовсе... наверняка никому не нужный счетчик непоймичего.

D
На сайте с 28.06.2008
Offline
1101
#4

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

Еще как вариант - изменитить логику вывода - выводить список постов с сортировкой не по дате, а по ID, на ID по идее должен быть первичный ключ и будет в разы быстрее.

danforth
На сайте с 18.12.2015
Offline
153
#5

он и так использует PK для подсчета, проблема в том, что у него WHERE, а без table scan на низком кардиналити у индекса будет перформанс ещё хуже, вот прямо сходил в доку и взял оттуда:

You are using a key with low cardinality (many rows match the key value) through another column. In this case, MySQL assumes that by using the key it probably will do many key lookups and that a table scan would be faster.

Этот запрос вряд ли отвечает за сам список постов, скорее за пагинатор, который определяет лимиты для последней страницы. Его только кешировать можно. Можно ещё повесить колонку с рандомным uuid, и на неё индекс, где WHERE условия будут совпадать. И потом по ней делать COUNT, но это костыль и так делать не надо. Лучше кешировать, да хоть в файл, и то будет быстрее 6 секунд, не говоря уже о memcached/redis.

iccup
На сайте с 01.05.2016
Offline
195
#6

Вобщем был у меня сервер уже с настроенным my.cnf -

[mysqld]
collation-server = utf8_general_ci
character-set-server = utf8
local-infile=0
innodb_file_per_table = 1
pid-file = /var/run/mysqld/mysqld.pid
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
bind-address = 127.0.0.1
max_allowed_packet = 128M
log-slow-queries=/tmp/slow_queries.log
long_query_time=5
key_buffer_size= 2048M
## Cache
thread-cache-size = 16
table-open-cache = 1024
table-definition-cache = 1024
query-cache-size = 16M
query-cache-limit = 512K

## Per-thread Buffers
sort-buffer-size = 128K
read-buffer-size = 128K
read-rnd-buffer-size = 128K
join-buffer-size = 256K

#net_buffer_length = 2K
#thread_stack = 128K


## Temp Tables
tmp-table-size = 16M
max-heap-table-size = 16M

## Networking
back-log = 100
max-connections = 32
max-connect-errors = 10000
max-allowed-packet = 16M
interactive-timeout = 30
wait-timeout = 30

### Storage Engines

default-storage-engine = MyISAM
#default-storage-engine = InnoDB
#innodb = FORCE
#skip-innodb

## MyISAM
key-buffer-size = 16M
myisam-sort-buffer-size = 4M

## InnoDB
#innodb-buffer-pool-size = 1M
#innodb-log-buffer-size = 1M
#innodb_additional_mem_pool_size= 1M
#innodb-log-file-size = 100M
#innodb-file-per-table = 1
#innodb-open-files = 300
#innodb_flush_method = O_DIRECT

## Replication
server-id = 1
#log-bin = /var/lib/mysqllogs/bin-log
#relay-log = /var/lib/mysqllogs/relay-log
relay-log-space-limit = 16G
expire-logs-days = 7
#read-only = 1
#sync-binlog = 1
#log-slave-updates = 1
#binlog-format = STATEMENT
#auto-increment-offset = 1
#auto-increment-increment = 2

[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

тупо скопировал и все залетало)

danforth
На сайте с 18.12.2015
Offline
153
#7

Залетало у вас из-за

query-cache-size = 16M
query-cache-limit = 512K

которое на MySQL 8.0.3 уже не прокатит. да и в целом, конфиг такой себе.

обычно query_cache включают, и если на реальном workload он помогает, тогда его оставляют. но помогать он может только при убогом дизайне приложения. когда у вас есть запись, query_cache сбрасывается, а т.к. его фронтенд работает в 1 поток, то легко наткнуться на блокировку мьютексов. Другими словами, если у вас на 1000 чтений 1 запись - вам это поможет. Если у вас 1 запись на 50-100 чтений - может только усугубить.

И да, у вас сейчас конфиг заточен скорее под myisam. Если у вас innodb - можно по лучше потюнить.

LEOnidUKG
На сайте с 25.11.2006
Offline
1722
#8
Это обращение к главной странице, там ничего особенного, просто список постов отсортированных по дате.

И наверное с постраничной навигацией?

Также у вас таблицы в innodb или myisam? Если первое то он туго COUNT кушает, а вот с myisam не должно быть проблем.

Но как указали выше если у вас innodb то у вас вообще нет настроек под него.

Также у вас как идёт наполнение сайта? Автоматически т.е. парсер работает?

✅ Мой Телеграм канал по SEO, оптимизации сайтов и серверов: https://t.me/leonidukgLIVE ✅ Качественное и рабочее размещение SEO статей СНГ и Бурж: https://getmanylinks.ru/
iccup
На сайте с 01.05.2016
Offline
195
#9
LEOnidUKG:
И наверное с постраничной навигацией?

Также у вас таблицы в innodb или myisam? Если первое то он туго COUNT кушает, а вот с myisam не должно быть проблем.

Но как указали выше если у вас innodb то у вас вообще нет настроек под него.

Также у вас как идёт наполнение сайта? Автоматически т.е. парсер работает?

Таблицы myisam, наполнения автоматического нет. Пока полет нормальный, будем решать проблемы по мере их поступления.

Александр
На сайте с 17.07.2009
Offline
371
#10
Dram:
У меня тоже есть такой тяжелый каунт на главной, я кеширую этот запрос через мем кеш, и проблема пропала.

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

Сайты на WordPress тут просто летают! (https://vk.cc/atAGUU)

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