powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Требуется помощь в оптимизации запроса
66 сообщений из 66, показаны все 3 страниц
Требуется помощь в оптимизации запроса
    #38766285
okuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Исходный запрос требующийся оптимизировать:

авторSELECT
t.id AS t0_c0,
t.catid AS t0_c1,
t.title AS t0_c2,
t.object AS t0_c3,
t.description AS t0_c4,
t.image AS t0_c5,
t.votes_summ AS t0_c6,
t.votes_count AS t0_c7,
t.views AS t0_c8,
t.favorites AS t0_c9,
t.date AS t0_c10,
t.is_uniq AS t0_c11,
count(game_views.id) AS gv_cnt,
category.id AS t1_c0,
category.slug AS t1_c1,
category.title AS t1_c2,
category.description AS t1_c3,
category.meta_title AS t1_c4,
category.parent AS t1_c5,
category.total_views AS t1_c6,
game_views.id AS t4_c0,
game_views.game_id AS t4_c1,
game_views.date AS t4_c2,
game_views.user_id AS t4_c3
FROM `game` `t` LEFT OUTER JOIN `category` `category` ON (`t`.`catid`=`category`.`id`) INNER JOIN `game_views` `game_views` ON (`game_views`.`game_id`=`t`.`id`)
WHERE (`game_views`.`date` > DATE(NOW() - INTERVAL 7 DAY))
GROUP BY game_views.game_id
ORDER BY gv_cnt DESC
LIMIT 28 OFFSET 224

Скорость выполнения запроса (в среднем): 5 сек.
В таблице хранится: 6998873 строк
Тип таблицы: InnoDB


Скриншоты EXPLAIN EXTENDED SELECT.... и SHOW WARNINGS:
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38766292
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
SELECT
t.id AS t0_c0,
t.catid AS t0_c1,
t.title AS t0_c2,
t.object AS t0_c3,
t.description AS t0_c4,
t.image AS t0_c5,
t.votes_summ AS t0_c6,
t.votes_count AS t0_c7,
t.views AS t0_c8,
t.favorites AS t0_c9,
t.date AS t0_c10,
t.is_uniq AS t0_c11,
count(game_views.id) AS gv_cnt,
category.id AS t1_c0,
category.slug AS t1_c1,
category.title AS t1_c2,
category.description AS t1_c3,
category.meta_title AS t1_c4,
category.parent AS t1_c5,
category.total_views AS t1_c6,
game_views.id AS t4_c0,
game_views.game_id AS t4_c1,
game_views.date AS t4_c2,
game_views.user_id AS t4_c3

FROM `game` `t`  
  LEFT OUTER JOIN `category` `category` ON (`t`.`catid`=`category`.`id`)  
  INNER JOIN `game_views` `game_views` ON (`game_views`.`game_id`=`t`.`id`)
WHERE (`game_views`.`date` > DATE(NOW() - INTERVAL 7 DAY))
GROUP BY game_views.game_id
ORDER BY gv_cnt DESC
LIMIT 28 OFFSET 224

Переформатировал запрос для большей читабельности
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38766298
okuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Поправка:

В таблице game_views хранится: 6998873 строк
В таблице game хранится: 80000 строк
Тип всех таблиц: InnoDB
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38766301
okuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
miksoft, спасибо)
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38766303
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я бы попробовал создать индекс по полю `game_views`.`date`.
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38766348
okuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
miksoft,

индексы уже созданы, забыл указать это в теме
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38766353
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
okuznetsovиндексы уже созданыСорри, проглядел в плане.
На будущее - не надо постить картинки, лучше показывать результат SHOW CREATE TABLE.
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38766361
Фотография javajdbc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1. напрашивается что бы category была
обязательная связка от game. Тогда
не нужно LEFT JOIN а просто JOIN.

2. добавить двоиной индекс (date,game_id)

3. переписать селект так:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
SELECT *
FROM
(
SELECT
game_views.gaim_id
count(game_views.id) AS gv_cnt
FROM  `game_views` `game_views` ON (`game_views`.`game_id`=`t`.`id`)
WHERE (`game_views`.`date` > DATE(NOW() - INTERVAL 7 DAY))
GROUP BY game_views.game_id
ORDER BY gv_cnt DESC
LIMIT 28 OFFSET 224
) t1
JOIN game ON ..............
JOIN category ON ............
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38766377
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
javajdbc1. напрашивается что бы category была
обязательная связка от game. Тогда
не нужно LEFT JOIN а просто JOIN.Без разницы в данном случае.
javajdbc2. добавить двоиной индекс (date,game_id)Для чего? не вижу от него пользы.
javajdbc3. переписать селект так:Я только не уверен, что поле `game`.id уникальное. К сожалению, нам этого не показали.
Но в целом с переписыванием согласен.
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38766380
Фотография javajdbc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
в типографии ошиблись,
следует читать:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
SELECT *
FROM
(
SELECT
game_views.gaim_id
count(game_views.id) AS gv_cnt
FROM  `game_views` `game_views` 
WHERE (`game_views`.`date` > DATE(NOW() - INTERVAL 7 DAY))
GROUP BY game_views.game_id
ORDER BY gv_cnt DESC
LIMIT 28 OFFSET 224
) t1
JOIN game ON ..............
JOIN category ON ............
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38766385
okuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
miksoft,

ок
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38766389
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
javajdbcв типографии ошиблись,Еще в типографии остальные поля из game_views пропустили.
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38766392
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miksoft
Код: sql
1.
t4_c3

Не завидую я тому, кто это отлаживать будет.
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38766396
Фотография javajdbc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miksoftjavajdbc1. напрашивается что бы category была
обязательная связка от game. Тогда
не нужно LEFT JOIN а просто JOIN.Без разницы в данном случае.
javajdbc2. добавить двоиной индекс (date,game_id)Для чего? не вижу от него пользы.
javajdbc3. переписать селект так:Я только не уверен, что поле `game`.id уникальное. К сожалению, нам этого не показали.
Но в целом с переписыванием согласен.


1. игра без категории -- некузяво звучит с точки зрения задачи

2. там фильтр по дате а групировка по гайм_ид --
чёрт его знает , а вдруг поможет двойной индекс?

3. гейм_ид не уникальный в таблице гейм?
Ну это будет некузявая некузявость...
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38766410
okuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
miksoft,

Разумеется, все поля id во всех 3-х таблицах -> primary key и autoincrement
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38766416
okuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
miksoft,

сделал кто то до меня и до того кто был до меня)
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38766420
okuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
javajdbc,

спасибо, сейчас попробую
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38766427
Фотография javajdbc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miksoftjavajdbcв типографии ошиблись,Еще в типографии остальные поля из game_views пропустили.

Где Яростный Меч и ScareCrow когда в селекте есть поля
НЕ из Гроуп БУ ?
Почему я должен выполнять их работу?
:-)

у ТС -- неверный изначальный селект -- поля из gaim_view
не агрегированы.
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38766443
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
javajdbcГде Яростный Меч и ScareCrow когда в селекте есть поля
НЕ из Гроуп БУ ?
Почему я должен выполнять их работу?
:-)Это наш коллективный сизифов камень :)
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38766445
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
javajdbcу ТС -- неверный изначальный селект -- поля из gaim_view
не агрегированы.Ну значит ему все равно, что там выйдет.
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38766493
okuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
miksoftjavajdbcу ТС -- неверный изначальный селект -- поля из gaim_view
не агрегированы.Ну значит ему все равно, что там выйдет.

я понял, что не верный поэтому помощи прошу, иначе бы у меня всё работало и к вам не обратился бы
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38766494
okuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
javajdbcmiksoftпропущено...
Еще в типографии остальные поля из game_views пропустили.

Где Яростный Меч и ScareCrow когда в селекте есть поля
НЕ из Гроуп БУ ?
Почему я должен выполнять их работу?
:-)

у ТС -- неверный изначальный селект -- поля из gaim_view
не агрегированы.


Получаю ошибку в этой части запроса, не пойму как поправить:

SELECT
game_views.game_id
count(game_views.id) AS gv_cnt
FROM `game_views` `game_views`
WHERE (`game_views`.`date` > DATE(NOW() - INTERVAL 7 DAY))
GROUP BY game_views.game_id
ORDER BY gv_cnt DESC
LIMIT 28 OFFSET 224

[Err] 1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'count(game_views.id) AS gv_cnt
FROM `game_views` `game_views`
WHERE (`game_v' at line 3
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38766498
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
okuznetsov,

запятую забыли на предыдущей строчке
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38767081
okuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
javajdbcв типографии ошиблись,
следует читать:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
SELECT *
FROM
(
SELECT
game_views.gaim_id
count(game_views.id) AS gv_cnt
FROM  `game_views` `game_views` 
WHERE (`game_views`.`date` > DATE(NOW() - INTERVAL 7 DAY))
GROUP BY game_views.game_id
ORDER BY gv_cnt DESC
LIMIT 28 OFFSET 224
) t1
JOIN game ON ..............
JOIN category ON ............




В процессе изучения запроса выяснилось, что группировка по left join не нужна, т.е. категория для игры ни где не задействуется, поэтому не нужна в запросе. В результате получились два запроса, вроде бы оба одинаково правильных. Хотелось бы чтобы вы порекомендовали какой из них более правильный (может быть с точки зрения качественного стиля написания или рассчитанный на обработку при росте в будущем нагрузки)?


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
SELECT *
FROM
(
SELECT
game_views.game_id,
count(game_views.id) AS gv_cnt
FROM  `game_views` `game_views` 
WHERE (`game_views`.`date` > DATE(NOW() - INTERVAL 7 DAY))
GROUP BY game_views.game_id
ORDER BY gv_cnt DESC
LIMIT 28 OFFSET 224
) t1
JOIN game ON (game.id=`t1`.`game_id`)


или


SELECT *
FROM `game` `game` JOIN
(
SELECT
game_views.game_id,
count(game_views.id) AS gv_cnt
FROM `game_views` `game_views`
WHERE (`game_views`.`date` > DATE(NOW() - INTERVAL 7 DAY))
GROUP BY game_views.game_id
ORDER BY gv_cnt DESC
LIMIT 28 OFFSET 224
) as t1 ON (`game`.`id`=`t1`.`game_id`)
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38767111
okuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
1) Также хотелось бы узнать можно ли что-то сделать и с этим запросом:

<pre class="src lang-sql">
SELECT * FROM `game` `t` WHERE t.id <> 208405 ORDER BY rand() LIMIT 15;
</pre>

выполняется в среднем от 0.5 - 1 сек, но бывают моменты когда более 3 секунд

EXPLAIN EXTENDED:

1 SIMPLE t range PRIMARY PRIMARY 4 49391 100,00 Using where; Using temporary; Using filesort


2) И хотелось бы что-то сделать с запросом такого плана (primary key соответственно в данной таблице нет):


<pre class="src lang-sql">
select ifnull(sum(data_length + index_length), 0) from information_schema.tables where table_schema = 'dbgwg';
</pre>


выполняется в среднем около 0.5 сек в среднем бывают моменты когда более 1 секунды

EXPLAIN EXTENDED следующий:

1 SIMPLE tables ALL TABLE_SCHEMA Using where; Open_full_table; Scanned 1 database



1) SHOW CREATE TABLE game

<pre class="src lang-sql">
CREATE TABLE `game` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`catid` int(11) NOT NULL,
`title` varchar(255) CHARACTER SET utf8 NOT NULL,
`object` text CHARACTER SET utf8 NOT NULL,
`description` text CHARACTER SET utf8 NOT NULL,
`image` varchar(255) NOT NULL,
`votes_summ` int(11) NOT NULL,
`votes_count` int(11) NOT NULL,
`views` int(11) NOT NULL,
`favorites` int(11) NOT NULL,
`date` datetime NOT NULL,
`is_uniq` tinyint(1) NOT NULL,
PRIMARY KEY (`id`),
KEY `catid` (`catid`),
KEY `date` (`date`),
KEY `favorites` (`favorites`),
KEY `views` (`views`),
KEY `title` (`title`),
KEY `votes_summ` (`votes_summ`,`votes_count`),
KEY `is_uniq` (`is_uniq`)
) ENGINE=InnoDB AUTO_INCREMENT=268052 DEFAULT CHARSET=latin1
</pre>

2) SHOW CREATE TABLE tables

<pre class="src lang-sql">CREATE TEMPORARY TABLE `TABLES` (
`TABLE_CATALOG` varchar(512) NOT NULL DEFAULT '',
`TABLE_SCHEMA` varchar(64) NOT NULL DEFAULT '',
`TABLE_NAME` varchar(64) NOT NULL DEFAULT '',
`TABLE_TYPE` varchar(64) NOT NULL DEFAULT '',
`ENGINE` varchar(64) DEFAULT NULL,
`VERSION` bigint(21) unsigned DEFAULT NULL,
`ROW_FORMAT` varchar(10) DEFAULT NULL,
`TABLE_ROWS` bigint(21) unsigned DEFAULT NULL,
`AVG_ROW_LENGTH` bigint(21) unsigned DEFAULT NULL,
`DATA_LENGTH` bigint(21) unsigned DEFAULT NULL,
`MAX_DATA_LENGTH` bigint(21) unsigned DEFAULT NULL,
`INDEX_LENGTH` bigint(21) unsigned DEFAULT NULL,
`DATA_FREE` bigint(21) unsigned DEFAULT NULL,
`AUTO_INCREMENT` bigint(21) unsigned DEFAULT NULL,
`CREATE_TIME` datetime DEFAULT NULL,
`UPDATE_TIME` datetime DEFAULT NULL,
`CHECK_TIME` datetime DEFAULT NULL,
`TABLE_COLLATION` varchar(32) DEFAULT NULL,
`CHECKSUM` bigint(21) unsigned DEFAULT NULL,
`CREATE_OPTIONS` varchar(255) DEFAULT NULL,
`TABLE_COMMENT` varchar(2048) NOT NULL DEFAULT ''
) ENGINE=MEMORY DEFAULT CHARSET=utf8</pre>
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38767208
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
okuznetsovВ результате получились два запросамне кажется или это один и тот же запрос, только с изменённым порядком таблиц в джойне?
okuznetsov 1) Также хотелось бы узнать можно ли что-то сделать и с этим запросом: Скорее всего нет. Ордер бай ранд() работает дубово: выбирается всё, подходящее под условие, для каждой записи генерируется рандом, результат сортируется. Учитывая, что сортировать надо практически всю таблицу (если ид у вас - ПК), то сортировка запросто может задействовать диск. Превед производительность.

А запросы к инфо_схема и не обязаны быть быстрыми. Неужели вам требуется выполнять их N раз в секунду?
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38767400
okuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
tanglirokuznetsovВ результате получились два запросамне кажется или это один и тот же запрос, только с изменённым порядком таблиц в джойне?
okuznetsov 1) Также хотелось бы узнать можно ли что-то сделать и с этим запросом: Скорее всего нет. Ордер бай ранд() работает дубово: выбирается всё, подходящее под условие, для каждой записи генерируется рандом, результат сортируется. Учитывая, что сортировать надо практически всю таблицу (если ид у вас - ПК), то сортировка запросто может задействовать диск. Превед производительность.

А запросы к инфо_схема и не обязаны быть быстрыми. Неужели вам требуется выполнять их N раз в секунду?

1) Именно так, один и тот же запрос, оформленный по разному. вроде бы по скорости одинаково выполняются. по стилю написания, т.е. хорошему тону какой соответствует?

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

Меня устраивает и следующий вариант реализации. Если вот таким образом сделать - это хорошее решение?

авторSELECT *
FROM game AS r1
JOIN
(
SELECT (RAND() * (SELECT MAX(id) FROM game)) AS id
) AS r2
WHERE r1.id >= r2.id
#ORDER BY r1.id ASC
LIMIT 15;
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38767401
okuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Расшифровка (на всякий случай):

JOIN добавляет все ID который больше или равны нашему случайному значению и мы выбираем ближайшего соседа, если равенство не возможно. НО как только 15 строк найдено мы останавливаемся.
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38767405
Фотография javajdbc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
okuznetsovРасшифровка (на всякий случай):

JOIN добавляет все ID который больше или равны нашему случайному значению и мы выбираем ближайшего соседа, если равенство не возможно. НО как только 15 строк найдено мы останавливаемся.


идея хорошая, реализация нет.
Поробуйте шаг за шагом:

1. заполучить максимально значение ИД
Код: sql
1.
select max(id) maxid from games



2. размножить сие значение 20 раз (с небольшим запасом на случайные повторения)

Код: sql
1.
2.
3.
4.
5.
select maxid
from 
(select max(id) maxid from games) z1
join (select 1 a union select 2 union select 3 union select 4 union select 5) z2
join (select 1 a union select 2 union select 3 union select 4) z3



3. помножить на РАНД

Код: sql
1.
2.
3.
4.
5.
select rand()*maxid
from 
(select max(id) maxid from games) z1
join (select 1 a union select 2 union select 3 union select 4 union select 5) z2
join (select 1 a union select 2 union select 3 union select 4) z3



4. выбрать наиближайшего реального соседа, допустим снизу

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
select 
(
  select id 
  from games 
  where id <= rand()*maxid 
  order by id desc 
  limit 1
) rand_real_id
from 
(select max(id) maxid from games) z1
join (select 1 a union select 2 union select 3 union select 4 union select 5) z2
join (select 1 a union select 2 union select 3 union select 4) z3



5 и выташить все поля нужных записей, снова отсортировать по ранд()
и взять 15 случайных значений

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
select g.*
from  
(
select 
(
  select id 
  from games 
  where id <= rand()*maxid 
  order by id desc 
  limit 1
) rand_real_id
from 
(select max(id) maxid from games) z1
join (select 1 a union select 2 union select 3 union select 4 union select 5) z2
join (select 1 a union select 2 union select 3 union select 4) z3
) z4
join games g on g.id = z4.rand_real_id 
order by rand()
limit 15
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38767408
okuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А в чём плохая реализация заключается? По времени на моей таблице в 7 000 000 строк запрос стал выполняться достаточно быстро - в пределах от 0.040 - 0.080 сек, на порядок ускорился.
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38767409
okuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вариант предложенный вами сейчас тоже изучу
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38767412
Фотография javajdbc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
okuznetsovА в чём плохая реализация заключается? По времени на моей таблице в 7 000 000 строк запрос стал выполняться достаточно быстро - в пределах от 0.040 - 0.080 сек, на порядок ускорился.

Ваш вариант выбирате 15 ид подряд начиная
с некоторого случайного числа.
Если это и есть ваше определение 15 случайных ИД --
то ок.

Мой варинат -- 15 реально случайно разбросаных ид
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38767416
okuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
javajdbcokuznetsovА в чём плохая реализация заключается? По времени на моей таблице в 7 000 000 строк запрос стал выполняться достаточно быстро - в пределах от 0.040 - 0.080 сек, на порядок ускорился.

Ваш вариант выбирате 15 ид подряд начиная
с некоторого случайного числа.
Если это и есть ваше определение 15 случайных ИД --
то ок.

Мой варинат -- 15 реально случайно разбросаных ид

Ваш вариант заинтересовал меня своим решением, и я попробовал потестировал его, в результате заметил одну не очень хорошую закономерность - случайные ИД генерируются в достаточно приближённом районе от максимального ID и ни как не из середины таблицы и тем более её начала. Возможно это какое-то странное совпадение, но я запускал запрос на выполнение подряд несколько сотен раз и интервалом в среднем 0.5 секунды.

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

Если с моим запросом всё в порядке тогда беру его)
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38767418
okuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
javajdbcokuznetsovА в чём плохая реализация заключается? По времени на моей таблице в 7 000 000 строк запрос стал выполняться достаточно быстро - в пределах от 0.040 - 0.080 сек, на порядок ускорился.

Ваш вариант выбирате 15 ид подряд начиная
с некоторого случайного числа.
Если это и есть ваше определение 15 случайных ИД --
то ок.

Мой варинат -- 15 реально случайно разбросаных ид



Можете помочь мне вот с этим запросом разобраться? Я не знаю и не понимаю пока для чего и зачем он нужен, но он в моём списке медленных запросов mysql-slow.log:

2) И хотелось бы что-то сделать с запросом такого плана (primary key соответственно в данной таблице нет):


авторselect ifnull(sum(data_length + index_length), 0) from information_schema.tables where table_schema = 'dbgwg';



выполняется в среднем около 0.5 сек в среднем бывают моменты когда более 1 секунды

EXPLAIN EXTENDED следующий:

1 SIMPLE tables ALL TABLE_SCHEMA Using where; Open_full_table; Scanned 1 database
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38767463
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
okuznetsovЯ не знаю и не понимаю пока для чего и зачем он нуженСчитает размер таблиц в схеме 'dbgwg'. По идее, чисто админская операция.
okuznetsovв результате заметил одну не очень хорошую закономерность - случайные ИД генерируются в достаточно приближённом районе от максимального ID+1
Как-то странно ранд работает. Ради интереса покрутил на одной из своих таблиц. Макс. ид = 20000 (впрочем, реально там идшники только до 15000), есть пропуски.
Код: sql
1.
2.
3.
4.
5.
select id,qwe,id<=qwe from (
  select id,rand()*20000 qwe
  from ls 
  having id <= qwe
  order by id desc ) t1 order by 1 desc

Так первой же строкой вылезаетidqweid<=qwe148164915.748075503620Это вообще *** как? если хэвингом эта строка должна была отсеяться в любом случае?? Впрочем, я проверял на старой версии - может, это какой-то известный баг и ТСу надо просто обновиться?

Впрочем, если вычисление ранда вынести в "статику", то работает нормально:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
select 
(
  select id 
  from games
  where id <= rand_ceil
  order by id desc 
  limit 1
) rand_real_id
from (
 select maxid*rand() as rand_ceil from 
 (select max(num) maxid from ls) z1
 join (select 1 a union select 2 union select 3 union select 4 union select 5) z2
 join (select 1 a union select 2 union select 3 union select 4) z3
) z4
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38767599
okuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
поправленный вами вариант, заработал, вижу стали генерироваться разные ИД, но скорость выполнения запроса упала в разы, на моей таблице составляет от 0.5 - 1 сек, это много. в том варианте который у javajdbc и менят- запрос выполняется от 0.040-0.100 сек.

спасибо за объяснение "Считает размер таблиц в схеме 'dbgwg'. По идее, чисто админская операция."
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38767625
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
okuznetsovно скорость выполнения запроса упала в разычудеса, да и только
а если по отдельности кусочки позапускать? даже не представляю, что именно там тормозить может...
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38767627
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кстати, вы несколько раз проверяли? у меня стабильно за 0,05с отрабатывает, только первый запуск был 0,2с.
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38767686
okuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
tanglirКстати, вы несколько раз проверяли? у меня стабильно за 0,05с отрабатывает, только первый запуск был 0,2с.

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

а как вместе - я заснял для вас здесь -
YouTube Video
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38767691
okuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
okuznetsov,

лучше на ютьюбе посмотрите, перейдите по прямой ссылке _
YouTube Video
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38767693
okuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
okuznetsov,
курсор мышки нужно было просто убрать:) и не чего не отрезалось бы:) заработался)
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38767756
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
okuznetsov, мда, хрень какая-то... сейчас проверил на тестовой таблице с 1М записей - по 5 секунд на запрос. В то же время если его превратить в
Код: sql
1.
2.
3.
4.
5.
select 
(select id from table where id <= 4 order by id desc limit 1) q1
,(select id from table where id <= 950909 order by id desc limit 1) q2
<...>
,(select id from table where id <= 976075 order by id desc limit 1) q20

или даже на такое (можно сказать, вообще тот же запрос, только "в лоб" написанный)
Код: sql
1.
2.
3.
4.
          select (select id from table where id <= 258493 order by id desc limit 1)
union all select (select id from table where id <= 978452 order by id desc limit 1)
<...>
union all select (select id from table where id <= 258741 order by id desc limit 1)

, то есть вручную подставить вычисленные границы в запрос, то выполняется моментально. WTF?
Грешил на рандом, но попробовал вообще вытащить эти 20 идшников во временную таблицу - один хрен. "В лоб" работает, а обход "опорной" таблицы с 20 записями тупит беспощадно...
Под спойлером - код. У кого есть мысли?
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
-- тестовая таблица, наполнена 1М записей
CREATE TABLE `tbl` (
	`id` INT(10) UNSIGNED NOT NULL,
	`oname` VARCHAR(50) NOT NULL DEFAULT '',
	PRIMARY KEY (`id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;

-- темп таблица для идшников; впрочем, и с инлайном всё то же самое
drop temporary table if exists qwe;
create temporary table qwe (id_ceil int);
insert into qwe 
  select ceil(maxid*rand()) 
  from (select max(id) maxid from tbl) z1
  join (select 1 a union select 2 union select 3 union select 4 union select 5) z2
  join (select 1 a union select 2 union select 3 union select 4) z3;

-- запрос
select qwe.id_ceil,
(
  select id
  from tbl
  where id <= qwe.id_ceil
  order by id desc limit 1
) rand_real_id
from qwe

Эксплейн. Вариант с темптаблицей хорош отсутствием кучи юнионовских строк.
idselect_typetabletypepossible_keyskeykey_lenrefrowsExtra1PRIMARYqweALL\N\N\N\N202DEPENDENT SUBQUERYtblindexPRIMARYPRIMARY4\N1118990Using where, Using index


время выполнения стабильно около 4.7 секунд.
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38767772
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мда. Тупо запустил 20 запросов по отдельности.
Код: plaintext
/* Affected rows: 0  Found rows: 20  Warnings: 0   Duration for 20 queries: 0,000 sec.  */
ЯННП.
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38767781
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tanglir,

В порядке танцев с бубном - сделайте ANALYZE TABLE обеим таблицам.
Какой движок получился у таблицы qwe?
Что-нибудь изменится, если id <= qwe.id_ceil заменить на id < qwe.id_ceil ?
Что-нибудь изменится, если создать индекс qwe (id_ceil) ?
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38767784
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Более того.
Код: sql
1.
select rand()*max(id) q from tbl

- 0,81сек. Стабильно.
Код: sql
1.
select rand()*(select max(id) from tbl) q

- 0сек. Стабильно.
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38767789
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tanglirБолее того.
Код: sql
1.
select rand()*max(id) q from tbl


- 0,81сек. Стабильно.
Код: sql
1.
select rand()*(select max(id) from tbl) q


- 0сек. Стабильно.
Эпичненько...
Планы?
Точная версия MySQL ?
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38767793
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miksoftВ порядке танцев с бубном - сделайте ANALYZE TABLE обеим таблицамдык это я первым делом после наполнения сделал
miksoftКакой движок получился у таблицы qwe?инно
miksoftЧто-нибудь изменится, если id <= qwe.id_ceil заменить на id < qwe.id_ceil ?нет
miksoftЧто-нибудь изменится, если создать индекс qwe (id_ceil) ?Ну, в первой строке эксплейна появился "using index", а толку. Время то же.
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38767804
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miksoftЭпичненько...
Планы?
Точная версия MySQL ?
Код: sql
1.
select rand()*max(id) q from tbl

idselect_typetabletypepossible_keyskeykey_lenrefrowsExtra1SIMPLEtblindex\NPRIMARY4\N1118990Using index
Код: sql
1.
select rand()*(select max(id) from tbl) q

idselect_typetabletypepossible_keyskeykey_lenrefrowsExtra1PRIMARY\N\N\N\N\N\N\NNo tables used2SUBQUERY\N\N\N\N\N\N\NSelect tables optimized away

5.0.67-community-nt-log
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38767806
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tanglir5.0.67Хм... а ежели посвежее взять?

Похоже, что недотумкивает оптимизатор, что в случае rand()*max(id) тоже можно Select tables optimized away.
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38767809
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miksoftа ежели посвежее взять?склфидл лежит, а то я бы уже проверил на "посвежее"
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38767827
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну поднялся фидл, я проверил.
http://sqlfiddle.com/#!2/cfbb99/2
версия 5.5.32(по умолчанию у них такая)
21 секунда, 25 секунд...
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38767831
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А вот тест ранд()-ов на той же версии: http://sqlfiddle.com/#!2/cfbb99/12
Первый запрос выполняется 1,3-1,4 секунды, второй - в пределах погрешности измерений.
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38767833
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tanglir,

Увы, на версии 5.6.6 m9 такая же ерунда :(
http://sqlfiddle.com/#!9/44f16/1
(он не лежит, но периодически дико тормозит)
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38767846
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tanglirНу поднялся фидл, я проверил.
http://sqlfiddle.com/#!2/cfbb99/2
версия 5.5.32(по умолчанию у них такая)
21 секунда, 25 секунд...Пришлось добавить commit;, а то отрабатывало моментально и давало пустой набор данных в итоге.
У меня стабильно получается 11,4 секунды.
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38767851
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miksofttanglirНу поднялся фидл, я проверил.
http://sqlfiddle.com/#!2/cfbb99/2
версия 5.5.32(по умолчанию у них такая)
21 секунда, 25 секунд...Пришлось добавить commit;, а то отрабатывало моментально и давало пустой набор данных в итоге.
У меня стабильно получается 11,4 секунды.Переключил на 5.6.6 - стало 3,3-3,4 секунды. План вроде бы не изменился.
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38767853
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miksoftУ меня стабильно получается 11,4 секунды.а должно быть 0 секунд - там всего-то и надо, что 20 раз дёрнуть индекс
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #38767860
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ранды на 5.6.6 получше смотрятся, но всё равно 370мс против 160мс - многовато. И планы разные - первый с using index, а второй с optimized away.
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #39008814
okuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В прошлый раз я остановился на этой реализации:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
SELECT *
FROM game AS r1
JOIN
(
SELECT (RAND() * (SELECT MAX(id) FROM game)) AS id
) AS r2
WHERE r1.id >= r2.id
#ORDER BY r1.id ASC
LIMIT 15;




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

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
SELECT `game`.*
FROM (
    SELECT id
    FROM `game`
    ORDER BY RAND()
    LIMIT 15
)  
AS ids 
JOIN `game` ON (`game`.id = ids.id)



Хотелось бы узнать ваше мнение, стоит ли использовать такой вариант с ORDER BY RAND()? На данный момент данные по таблице:
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #39008816
okuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #39008823
okuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
okuznetsov

Ошибся, верный скриншот ниже:
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #39008829
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
okuznetsovХотелось бы узнать ваше мнение, стоит ли использовать такой вариант с ORDER BY RAND()?Если время выполнения запроса вас устраивает, то почему бы и нет?
Но учтите, что оно будет расти линейно с ростом количества записей в таблице или даже быстрее.

Я только не понял, зачем вы джойните таблицу саму на себя по первичному ключу?
Почему не так:
Код: sql
1.
2.
3.
4.
SELECT *
FROM `game`
ORDER BY RAND()
LIMIT 15

?
Хотя при очень большом количестве записей, возможно, вариант с джойном окажется быстрее.
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #39008833
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
P.S. Скриншоты лучше делать в формате PNG с 256 цветами. Так и размер файла будет меньше, и текст замыливаться не будет.
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #39008849
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
okuznetsov, ну если вас устраивает производительность ордер бай ранд, то почему бы и нет. Нормальный-то вариант мускль асиливать так до сих пор и не умеет...
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #39008855
okuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
miksoft
Я только не понял, зачем вы джойните таблицу саму на себя по первичному ключу?
Почему не так:
Код: sql
1.
2.
3.
4.
SELECT *
FROM `game`
ORDER BY RAND()
LIMIT 15

?

Хотя при очень большом количестве записей, возможно, вариант с джойном окажется быстрее.



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

Как раз этот запрос мы и оптимизировали в этой теме выше, первоначально он был таким как вы
написали.

Всё верно, запрос с джойнами оказался намного быстрее.
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #39008856
okuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
miksoftP.S. Скриншоты лучше делать в формате PNG с 256 цветами. Так и размер файла будет меньше, и текст замыливаться не будет.

хорошо, спасибо
...
Рейтинг: 0 / 0
Требуется помощь в оптимизации запроса
    #39008858
okuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
tanglirokuznetsov, ну если вас устраивает производительность ордер бай ранд, то почему бы и нет. Нормальный-то вариант мускль асиливать так до сих пор и не умеет...

Согласен, не умеет. Спасибо.
...
Рейтинг: 0 / 0
66 сообщений из 66, показаны все 3 страниц
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Требуется помощь в оптимизации запроса
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]