powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / order by по полям из разных таблиц
9 сообщений из 9, страница 1 из 1
order by по полям из разных таблиц
    #38462880
miZeratti
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть табличка юзеров (~20k) и табличка со статистикой по юзерам (1-1)
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `i_user__name` (`name`)
) ENGINE=MyISAM

CREATE TABLE `stat` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `val` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `i_stat__val` (`val`),
  KEY `i_stat__user_val` (`user_id`,`val`),
  KEY `i_stat__val_user` (`val`,`user_id`)
) ENGINE=MyISAM



Запросик выводит ТОП юзеров по рейтингу
Код: sql
1.
2.
3.
4.
5.
select u.id 
from user u 
join stat s on s.user_id = u.id 
order by s.val, u.name 
limit 20



По эксплейну запрос пробегает по всем строкам.
Код: sql
1.
2.
3.
4.
5.
6.
+----+-------------+-------+--------+---------------+------------------+---------+----------------+-------+----------------------------------------------+
| id | select_type | table | type   | possible_keys | key              | key_len | ref            | rows  | Extra                                        |
+----+-------------+-------+--------+---------------+------------------+---------+----------------+-------+----------------------------------------------+
|  1 | SIMPLE      | s     | index  | NULL          | i_stat__val_user | 8       | NULL           | 20460 | Using index; Using temporary; Using filesort |
|  1 | SIMPLE      | u     | eq_ref | PRIMARY       | PRIMARY          | 4       | test.s.user_id |     1 |                                              |
+----+-------------+-------+--------+---------------+------------------+---------+----------------+-------+----------------------------------------------+



Возможно ли оптимизировать этот запрос без денормализации данных?
...
Рейтинг: 0 / 0
order by по полям из разных таблиц
    #38462928
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообще я бы не стал утверждать, чтоmiZerattiПо эксплейну запрос пробегает по всем строкам.Судя по тому, что используется индекс {"вал","ид"}, запрос выполняется примерно так: читается таблица "стат"(в порядке индекса), к каждой полученной записи сразу джойнятся соотв.записи из "юзер", и как только таких результирующих записей записей наберётся 20, чтение таблиц прекратится. 20460 - это просто наихудший возможный вариант, сервер ведь не знает, что у вас там 1-1, он подстраховывается на случай, если не всем "стат"ам соответствуют "юзер"ы.

PS. Но если очень хочется красивогомалоциферного эксплейна , то можно так:
Код: sql
1.
2.
3.
4.
5.
6.
select u.id 
from user u 
join (select user_id from stat order by s.val limit 20
) s on s.user_id = u.id 
order by s.val, u.name 
limit 20
...
Рейтинг: 0 / 0
order by по полям из разных таблиц
    #38464240
miZeratti
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
tanglir,
к сожалению, это будет работать неправильно, если в отсортированом по val списке записи с 15 по 30 будут иметь одинаковое значение val
...
Рейтинг: 0 / 0
order by по полям из разных таблиц
    #38464382
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miZerattiэто будет работать неправильнокак именно "неправильно"? объясните, в чём будет заключаться разница между "правильным" и "неправильным" результатами?
...
Рейтинг: 0 / 0
order by по полям из разных таблиц
    #38465826
miZeratti
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
tanglirmiZerattiэто будет работать неправильнокак именно "неправильно"? объясните, в чём будет заключаться разница между "правильным" и "неправильным" результатами?

для упрощения возьмем исходную таблицу из 6 строк и запрос с "limit 3":
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
val name
----------
1 name111
2 name222
3 name333
3 name222
3 name000
3 name111


(имена повторяются для наглядности сортировки)

По вашему алгоритму выберутся строки:
Код: sql
1.
2.
3.
4.
5.
val name
----------
1 name111
2 name222
<и еще какая-то строка с val = 3>



а нужно:
Код: sql
1.
2.
3.
4.
5.
val name
----------
1 name111
2 name222
3 name000
...
Рейтинг: 0 / 0
order by по полям из разных таблиц
    #38465895
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
3.
4.
5.
6.
select u.id 
from user u 
join (select user_id from stat order by s.val limit 20
) s on s.user_id = u.id 
order by s.val, u.name 
limit 20

в "s" выберутся 1,2,3
в запросе, соответственно, выберется именно то, что вы описали как "нужное"
с чего вы взяли, что val=3 будет соответствовать "какая-то", а не первая по name запись? на "внешний" ордербай внимательно посмотрите.
...
Рейтинг: 0 / 0
order by по полям из разных таблиц
    #38465896
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А, нет, понял. Да, есть такое :)
...
Рейтинг: 0 / 0
order by по полям из разных таблиц
    #38467152
deblogger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В мане оптимизации сортировки посвящена обширная статья http://dev.mysql.com/doc/refman/5.0/en/order-by-optimization.html

Пишут что ваш случай подпадает под файлсорт неизбежно.
...
Рейтинг: 0 / 0
order by по полям из разных таблиц
    #38467153
deblogger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Случай ТСа.

Но есть теория что если бы отношение сливалось в экстазе using() то эксплейн был бы красивее.
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / order by по полям из разных таблиц
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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