MySQL скорость запроса. почему запрос из таблиц памяти с таблицей tmp медленнее, чем прямой выбор? - PullRequest
0 голосов
/ 27 марта 2012

Я немного запутался в таком поведении 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 !! ?? но почему??? я работаю с таблицей ПАМЯТЬ .. почему это занимает так много времени? и почему это вообще сортирует? я убираю заказ по пункту

...