MySQL - тяжелый запрос

12
sidorka
На сайте с 17.08.2012
Offline
211
1343

Подскажите, как оптимизировать запрос такого вида:

SELECT *

FROM posts
JOIN sources ON posts.source_id = sources.id
JOIN categories_posts ON categories_posts.source_id = sources.id
WHERE categories_posts.category_id =1 AND posts.domain_id =1
ORDER BY `time` DESC
LIMIT 0 , 10

Время выполнения сейчас - от 10с и выше.

starting 	0.000011

checking query cache for query 0.000078
checking permissions 0.000003
checking permissions 0.000002
checking permissions 0.000003
Opening tables 0.000019
System lock 0.000006
Table lock 0.000028
init 0.000048
optimizing 0.000021
statistics 0.000031
preparing 0.000033
Creating tmp table 0.000233
executing 0.000003
Copying to tmp table 10.306402
Sorting result 0.001204
Sending data 0.000199
end 0.000004
removing tmp table 0.000994
end 0.000006
query end 0.000004
freeing items 0.000256
storing result in query cache 0.000012
logging slow query 0.000003
logging slow query 0.000002
cleaning up 0.000005

Основные затраты на копирование в промежуточную таблицу - Copying to tmp table 10.306402.

Боты сервак просто ложат на лопатки. :( Пока частично решил вопрос кэшированием страниц, но при первом обращении иногда до 40-50с доходит.

Дешевые домены для дорвеев и не только - от 55р (https://goo.gl/Wtnwqp)
siv1987
На сайте с 02.04.2009
Offline
427
#1

SHOW CREATE TABLE categories_posts и posts

Милованов Ю.С
На сайте с 24.01.2008
Offline
196
#2

Сколько в таблице записей?

Подпись))
sidorka
На сайте с 17.08.2012
Offline
211
#3

SQL-запрос: SHOW CREATE TABLE categories_posts;


starting 0.000029
checking permissions 0.000007
Opening tables 0.000043
query end 0.000004
freeing items 0.000012
logging slow query 0.000003
cleaning up 0.000002

categories_posts CREATE TABLE `categories_posts` (
`source_id` int(11) NOT NULL,
`category_id` int(11) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8

SQL-запрос: SHOW CREATE TABLE posts;


starting 0.000025
checking permissions 0.000006
Opening tables 0.000044
query end 0.000002
freeing items 0.000010
logging slow query 0.000002
cleaning up 0.000003

posts CREATE TABLE `posts` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`source_id` int(11) NOT NULL,
`domain_id` int(11) NOT NULL,
`text` text,
`time` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=280356 DEFAULT CHARSET=utf8


---------- Добавлено 10.07.2013 в 20:21 ----------

Милованов Ю.С, чуть больше, чем много :)

---------- Добавлено 10.07.2013 в 20:27 ----------

в posts порядка 10 миллионов, в sources порядка 80к, в categories_posts - до 100 миллионов. Это предельные значения. Сейчас там меньше, но все равно много.
siv1987
На сайте с 02.04.2009
Offline
427
#4

sidorka, вам нужно открыть для себя индексы.

categories_posts

category_id - поставить индекс

source_id если это уникальное значение в пределах таблицы сделать PRIMARY KEY. Если нет - хоть поставьте суррогатный ключ.

На posts можно

один индекс - source_id

второй составной - domain_id, time

Хотя может спецы подскажут как лучше тут сделать индексы

Ну уже покажите структуру и третей таблицы. Только скопируйте без профилирования.

Милованов Ю.С
На сайте с 24.01.2008
Offline
196
#5

posts.source_id - индекс

posts.domain_id - индекс

categories_posts.source_id - индекс

categories_posts.category_id - индекс

sources.id - индекс

индекс может быть любой(Unuque, primary, key). После простановки индексов можете показать результаты.

siv1987
На сайте с 02.04.2009
Offline
427
#6
Милованов Ю.С:
После простановки индексов можете показать результаты.
sidorka:
в posts порядка 10 миллионов, в sources порядка 80к, в categories_posts - до 100 миллионов. Это предельные значения. Сейчас там меньше, но все равно много.

Ждем результат... часа через пять :D

sidorka
На сайте с 17.08.2012
Offline
211
#7

Посыпаю голову пеплом :(

starting 	0.000012

checking query cache for query 0.000079
checking permissions 0.000003
checking permissions 0.000002
checking permissions 0.000004
Opening tables 0.000015
System lock 0.000007
Table lock 0.000037
init 0.000047
optimizing 0.000023
statistics 0.000088
preparing 0.000028
executing 0.000003
Sorting result 0.009202
Sending data 0.001352
end 0.000007
query end 0.000003
freeing items 0.000113
storing result in query cache 0.000008
logging slow query 0.000002
cleaning up 0.000005
Отображает строки 0 - 9 (10 всего, запрос занял 0.0112 сек.) [time: 1373436180 - 1373412813]

Спс за советы. Не знал про индексы - всегда хватало первичных уникальных. Это применимо к JOIN или ускорение будет и в других случаях?

Зря сервак апнул :(

siv1987
На сайте с 02.04.2009
Offline
427
#8

Быстро...

И EXPLAIN SELECT уже покажите.

Что с третьей таблицы?

sidorka
На сайте с 17.08.2012
Offline
211
#9

starting 	0.000104

checking permissions 0.000006
checking permissions 0.000003
checking permissions 0.000005
Opening tables 0.000126
System lock 0.000007
Table lock 0.000025
init 0.000051
optimizing 0.000027
statistics 0.000104
preparing 0.000035
executing 0.000036
end 0.000012
query end 0.000003
freeing items 0.000045
logging slow query 0.000004
cleaning up 0.000004

Везде, где пересечения таблиц, потыкал индексы. Вроде шустренько стало.

---------- Добавлено 10.07.2013 в 21:17 ----------

Еще раз спасибо за совет.

siv1987
На сайте с 02.04.2009
Offline
427
#10

Сделали бы составной индекс domain_id + time как я вам сказал избавились бы от filesort

Сделайте отдельно копию таблиц, создайте пару тестовых значений и посмотрите что покажет EXPLAIN c составным индексом.

12

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