Медленная выборка из таблиц

12
R
На сайте с 19.07.2010
Offline
64
1091

Ребята помогите решить задачу, в таблице 4 миллиона записей, при выполнении запроса:

SELECT SQL_CACHE 9 AS test,N.*,

(SELECT NAME FROM news_regions where id = N.id_region) AS region,
(SELECT NAME FROM news_category where id = N.id_category) AS category,
(SELECT NAME FROM news_sources where id = N.id_source) AS source
FROM news_news N
WHERE 1=1
AND MONTH(N.date) = 1 AND YEAR(N.date) = 2014
ORDER BY N.id DESC
LIMIT 0,36;

думает очень долго - Отображает строки 0 - 29 (36 всего, запрос занял 2.9451 сек.)

можно в принципе чуть упростить убрав сортировку ORDER BY N.id DESC но тогда понятное дело вывод будет не тот, что нужен, может кто что придумает, у меня сейчас башка совсем не варит, сижу мучаюсь только.

Сейчас его пилю http://newsrbk.ru/ (http://newsrbk.ru/)
U
На сайте с 09.04.2015
Offline
28
#1

Две секунды - не так уж чтобы очень уж и долго. Может, браузер долго обрабатывает какие-то незакрытые теги?

dlyanachalas
На сайте с 15.09.2006
Offline
693
#2

Какой-то странный у вас запрос.

Здесь:

(SELECT NAME FROM news_regions where id = N.id_region) AS region,
(SELECT NAME FROM news_category where id = N.id_category) AS category,
(SELECT NAME FROM news_sources where id = N.id_source) AS source

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

Лечение: переписать, заменив запятые на конструкцию UNION.

R
На сайте с 19.07.2010
Offline
64
#3
umercomp:
Две секунды - не так уж чтобы очень уж и долго. Может, браузер долго обрабатывает какие-то незакрытые теги?

нет, это именно медленный запрос, я выше дал результат выполнения )

---------- Добавлено 10.05.2015 в 11:50 ----------

dlyanachalas:
Какой-то странный у вас запрос.

Здесь:



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

Лечение: переписать, заменив запятые на конструкцию UNION.

удалось ускорить немножко таким методом

N.date between '2014-01-01 00:00:00' and '2014-02-01 00:00:00'

Отображает строки 0 - 29 (36 всего, запрос занял 0.0227 сек.)

но думаю, что можно ещё ускорить

C
На сайте с 29.07.2014
Offline
8
#4

Вложенные селекты очень и очень медленное решение. Не уверен, но может быть пошустрее


SELECT SQL_CACHE 9 AS test,N.*, R.NAME as region, C.NAME as category, S.NAME FROM
FROM news_news N
LEFT JOIN news_regions R ON R.id = N.id_region
LEFT JOIN news_category C ON C.id = N.id_category
LEFT JOIN news_sources S ON S.id = N.id_source
WHERE 1=1
AND MONTH(N.date) = 1 AND YEAR(N.date) = 2014
ORDER BY N.id DESC
LIMIT 0,36;

NAME во вложенных селектах это параметр?

Еще посмотрите

EXPLAIN своего и предложенного мною запроса. Вполне возможно, что где то тут news_sources where id = N.id_source отсутствуют индексы. Так же желательно содержать индекс на дату. Он у Вас есть?

R
На сайте с 19.07.2010
Offline
64
#5
Comodo:
Вложенные селекты очень и очень медленное решение. Не уверен, но может быть пошустрее

NAME во вложенных селектах это параметр?

EXPLAIN своего и предложенного мною запроса. Вполне возможно, что где то тут news_sources where id = N.id_source отсутствуют индексы. Так же желательно содержать индекс на дату. Он у Вас есть?

спасибо за совет

да NAME это параметр

индексы вроде бы везде где надо есть, лучше ниже приведу всю таблицу

CREATE TABLE IF NOT EXISTS `news_news` (

`id` INT(11) NOT NULL AUTO_INCREMENT,
`tid` INT(11) NOT NULL DEFAULT '0',
`id_category` INT(11) NOT NULL DEFAULT '0',
`id_source` INT(11) NOT NULL DEFAULT '1',
`id_region` INT(11) NOT NULL DEFAULT '1',
`date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`title` VARCHAR(255) NOT NULL DEFAULT '',
`text` longtext NOT NULL,
`link` VARCHAR(255) NOT NULL DEFAULT '',
`image` VARCHAR(255) NOT NULL,
`counter` INT(11) NOT NULL DEFAULT '0',
`comment` INT(11) NOT NULL DEFAULT '0',
`seo_title` VARCHAR(255) NOT NULL,
`user_id` INT(11) NOT NULL,
`poll` INT(11) NOT NULL DEFAULT '0',
`hits` INT(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `id_region_id_category_id_source` (`id_region`,`id_category`,`id_source`),
KEY `id_category` (`id_category`),
KEY `image` (`image`),
KEY `category_image` (`id_category`,`image`),
KEY `id_region` (`id_region`),
KEY `date` (`date`),
KEY `id_source` (`id_source`),
KEY `counter` (`counter`),
KEY `region_category` (`id_category`,`id_region`),
KEY `category_date_source` (`id_category`,`date`,`id_source`),
KEY `link` (`link`),
KEY `region_category_source_date` (`id_region`,`id_category`,`id_source`,`date`),
KEY `regi2` (`id_region`,`id_category`,`date`),
KEY `source_region` (`id_source`,`id_region`),
KEY `user_id` (`user_id`),
KEY `hits` (`hits`),
KEY `counter_cat` (`id_category`,`counter`),
FULLTEXT KEY `FULLTEXT` (`text`,`title`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251 AUTO_INCREMENT=4824896 ;

кстати ваш запрос сильно не помог, вот время его выполнения

Отображает строки 0 - 29 (36 всего, запрос занял 3.0853 сек.)

C
На сайте с 29.07.2014
Offline
8
#6

Если Вы пользуетесь phpmyadmin (судя по строке со временем) он Вам показывает не совсем точное время. Попробуйте выполнить запрос с чекбоксом Profiling, и посмотрите EXPLAIN запроса, иначе можно только тыкать пальцем в небо о природе тормозов.

dlyanachalas
На сайте с 15.09.2006
Offline
693
#7

Делайте через UNION, будет быстрее всего.

[Удален]
#8

Джойн на мускуле с большим обьемом данных? Нуну

C
На сайте с 29.07.2014
Offline
8
#9
Джойн на мускуле с большим обьемом данных? Нуну

Простите, а что не так? Ваше "Нуну", судя по всему, означает что это применение JOIN на больших объемах данных - это плохая практика? Не буду ли я слишком назойлив, если попрошу пруф линк для Вашего замечания?

JOIN быстрее NESTED QUERIES 1, JOIN быстрее NESTED QUERIES 2.

[Удален]
#10

Comodo, вы не поняли ничего. С реально большими обьемами данных нужен не мускуль это раз, а хотя бы постгри. Второе - сфинкс (ну под конкретные задачи).

12

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