Я немного запутался в таком поведении mysql.
один запрос с предложением ORDER BY создает таблицу tmp (как показано в show profile) и выполняется быстрее, чем тот же запрос без заказа с помощью with не создает таблицу tmp. Зачем? и почему в выводе профиля появляется "сортировка", а ORDER BY отсутствует?
так, с самого начала.
у меня mysql5.1 на amazon m1.small экземпляр.
У меня есть 4 таблицы, такие как:
CREATE TABLE `meetings_m` (
`id` int(11) unsigned NOT NULL DEFAULT '0',
`name` varchar(255) DEFAULT NULL,
`address1` varchar(255) DEFAULT NULL,
`address2` varchar(255) DEFAULT NULL,
`city` varchar(255) DEFAULT NULL,
`state` varchar(50) DEFAULT NULL,
`zip` varchar(255) DEFAULT NULL,
`country` varchar(255) DEFAULT NULL,
`latitude` double NOT NULL,
`longitude` double NOT NULL,
`user_id` int(11) unsigned NOT NULL,
`image_url` varchar(250) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
KEY `name` (`name`)
) ENGINE=MEMORY DEFAULT CHARSET=latin1
CREATE TABLE `meeting_times_m` (
`id` int(11) unsigned NOT NULL DEFAULT '0',
`meeting_id` int(11) unsigned NOT NULL,
`day` varchar(255) NOT NULL,
`time` time NOT NULL,
`name` varchar(50) NOT NULL,
`format` varchar(255) DEFAULT NULL,
`notes` varchar(255) NOT NULL,
`program` varchar(255) NOT NULL,
`cancelled` varchar(10) NOT NULL DEFAULT 'False',
PRIMARY KEY (`id`),
KEY `meeting_id` (`meeting_id`),
KEY `program` (`program`)
) ENGINE=MEMORY DEFAULT CHARSET=latin1
CREATE TABLE `real_meeting_tags_m` (
`id` int(10) unsigned NOT NULL DEFAULT '0',
`meeting_id` int(10) unsigned NOT NULL,
`tag_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `meeting_id` (`meeting_id`),
KEY `tag_id` (`tag_id`)
) ENGINE=MEMORY DEFAULT CHARSET=latin1
CREATE TABLE `tags_m` (
`id` int(11) unsigned NOT NULL DEFAULT '0',
`name` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MEMORY DEFAULT CHARSET=latin1
=========================
теперь я бегу
SELECT SQL_CALC_FOUND_ROWS
Meeting.*,
3959.87*acos(sin(radians(37.7858))*sin(radians(latitude))+cos(radians(37.7858))*cos(radians(latitude))*cos(radians(-122.406-longitude))) as distance,
count(`MeetingTag`.`id`) as tag_count,
group_concat(distinct Tag.name) as tags,
group_concat(distinct Tag.id) as tag_ids
FROM
`meetings_m` AS `Meeting`
LEFT JOIN `meeting_times_m` AS `MeetingTime` ON (`MeetingTime`.`meeting_id` = `Meeting`.`id`)
INNER JOIN `real_meeting_tags_m` AS `MeetingTag` ON (`MeetingTag`.`meeting_id`=`Meeting`.`id` AND (`MeetingTag`.`tag_id` in (9,8,16,14,4,2,5,15,11,7,10,13,3,6)))
LEFT JOIN `tags_m` AS `Tag` ON (`MeetingTag`.`tag_id` = `Tag`.`id`)
WHERE
3959.87*acos(sin(radians(37.7858))*sin(radians(latitude))+cos(radians(37.7858))*cos(radians(latitude))*cos(radians(-122.406-longitude))) <= '204.0'
AND `MeetingTime`.`program` = ('AA') AND ((`Meeting`.`name` LIKE 'AA%') OR (`MeetingTime`.`program` LIKE 'AA%'))
GROUP BY
`MeetingTag`.`meeting_id`
ORDER BY `distance` ASC
LIMIT 22
этот запрос выполняется 36 секунд, а его профиль
| Status | Duration |
+--------------------------------+----------+
| starting | 0.000027 |
| checking query cache for query | 0.000217 |
| checking permissions | 0.000005 |
| checking permissions | 0.000002 |
| checking permissions | 0.000003 |
| checking permissions | 0.000005 |
| Opening tables | 0.000019 |
| System lock | 0.000004 |
| Table lock | 0.000059 |
| init | 0.000075 |
| optimizing | 0.000030 |
| statistics | 0.000081 |
| preparing | 0.000035 |
| Creating tmp table | 0.000059 |
| executing | 0.000004 |
| Copying to tmp table | 0.352465 |
| Creating sort index | 0.001807 |
| Copying to group table | 0.005540 |
| Sorting result | 0.000776 |
| Sending data | 0.002716 |
| end | 0.000006 |
| removing tmp table | 0.000009 |
| end | 0.000003 |
| removing tmp table | 0.000425 |
| end | 0.000007 |
| query end | 0.000004 |
| freeing items | 0.000020 |
| removing tmp table | 0.000005 |
| freeing items | 0.000005 |
| removing tmp table | 0.000004 |
| freeing items | 0.000526 |
| storing result in query cache | 0.000010 |
| logging slow query | 0.000003 |
| cleaning up | 0.002318 |
0,35 секунды при копировании в таблицу tmp.
объяснить это
+----+-------------+-------------+--------+--------------------+------------+---------+----------------------------------+------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+--------+--------------------+------------+---------+----------------------------------+------+----------------------------------------------+
| 1 | SIMPLE | MeetingTime | ref | meeting_id,program | program | 257 | const | 7129 | Using where; Using temporary; Using filesort |
| 1 | SIMPLE | MeetingTag | ref | meeting_id,tag_id | meeting_id | 4 | stepsaway.MeetingTime.meeting_id | 2 | Using where |
| 1 | SIMPLE | Tag | eq_ref | PRIMARY | PRIMARY | 4 | stepsaway.MeetingTag.tag_id | 1 | |
| 1 | SIMPLE | Meeting | eq_ref | PRIMARY,name | PRIMARY | 4 | stepsaway.MeetingTag.meeting_id | 1 | Using where |
+----+-------------+-------------+--------+--------------------+------------+---------+----------------------------------+------+----------------------------------------------+
так что я хочу сделать запрос быстрее. так что я думаю, что пропуск таблицы tmp поможет. после прочтения некоторых мужчин я меняю group by
с MeetingTag.meeting_id на MeetingTime.meeting_id (как они есть) и удаляю order by
предложение
теперь запрос
SELECT SQL_CALC_FOUND_ROWS
Meeting.*,
3959.87*acos(sin(radians(37.7858))*sin(radians(latitude))+cos(radians(37.7858))*cos(radians(latitude))*cos(radians(-122.406-longitude))) as distance,
count(`MeetingTag`.`id`) as tag_count,
group_concat(distinct Tag.name) as tags,
group_concat(distinct Tag.id) as tag_ids
FROM
`meetings_m` AS `Meeting`
LEFT JOIN `meeting_times_m` AS `MeetingTime` ON (`MeetingTime`.`meeting_id` = `Meeting`.`id`)
INNER JOIN `real_meeting_tags_m` AS `MeetingTag` ON (`MeetingTag`.`meeting_id`=`Meeting`.`id` AND (`MeetingTag`.`tag_id` in (9,8,16,14,4,2,5,15,11,7,10,13,3,6)))
LEFT JOIN `tags_m` AS `Tag` ON (`MeetingTag`.`tag_id` = `Tag`.`id`)
WHERE
3959.87*acos(sin(radians(37.7858))*sin(radians(latitude))+cos(radians(37.7858))*cos(radians(latitude))*cos(radians(-122.406-longitude))) <= '204.0'
AND `MeetingTime`.`program` = ('AA') AND ((`Meeting`.`name` LIKE 'AA%') OR (`MeetingTime`.`program` LIKE 'AA%'))
GROUP BY
`MeetingTime`.`meeting_id`
LIMIT 22
объяснить это
+----+-------------+-------------+--------+--------------------+------------+---------+----------------------------------+------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+--------+--------------------+------------+---------+----------------------------------+------+-----------------------------+
| 1 | SIMPLE | MeetingTime | ref | meeting_id,program | program | 257 | const | 7129 | Using where; Using filesort |
| 1 | SIMPLE | MeetingTag | ref | meeting_id,tag_id | meeting_id | 4 | stepsaway.MeetingTime.meeting_id | 2 | Using where |
| 1 | SIMPLE | Tag | eq_ref | PRIMARY | PRIMARY | 4 | stepsaway.MeetingTag.tag_id | 1 | |
| 1 | SIMPLE | Meeting | eq_ref | PRIMARY,name | PRIMARY | 4 | stepsaway.MeetingTag.meeting_id | 1 | Using where |
+----+-------------+-------------+--------+--------------------+------------+---------+----------------------------------+------+-----------------------------+
и время выполнения составляет 42 секунды.
профиль
+--------------------------------+----------+
| Status | Duration |
+--------------------------------+----------+
| starting | 0.000026 |
| checking query cache for query | 0.000211 |
| checking permissions | 0.000005 |
| checking permissions | 0.000003 |
| checking permissions | 0.000003 |
| checking permissions | 0.000005 |
| Opening tables | 0.000019 |
| System lock | 0.000003 |
| Table lock | 0.000058 |
| init | 0.000075 |
| optimizing | 0.000031 |
| statistics | 0.000082 |
| preparing | 0.000036 |
| executing | 0.000051 |
| Sorting result | 0.145705 |
| Sending data | 0.271131 |
| end | 0.000016 |
| removing tmp table | 0.000008 |
| end | 0.000006 |
| removing tmp table | 0.000004 |
| end | 0.000007 |
| query end | 0.000004 |
| freeing items | 0.000619 |
| storing result in query cache | 0.000010 |
| logging slow query | 0.000003 |
| cleaning up | 0.000006 |
+--------------------------------+----------+
сортировка результатов и отправка данных занимает даже больше времени, чем создание таблицы tmp !! ?? но почему???
я работаю с таблицей ПАМЯТЬ .. почему это занимает так много времени? и почему это вообще сортирует? я убираю заказ по пункту