Проблемы с оптимизацией соединения с MySQL - PullRequest
1 голос
/ 13 октября 2011

Я работаю с некоторыми операторами MySQL, которые используют соединения. Производительность для этих запросов, кажется, довольно низкая и может снизить время выполнения запроса. Ниже приведены несколько примеров запросов, которые я использую. Я новичок в операторах MySQL JOIN и мне было любопытно, если кто-нибудь может помочь мне оптимизировать их для повышения производительности.

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

SELECT * FROM tickets t 
LEFT Join customfieldvalues cv1 ON t.ticketid = cv1.typeid 
LEFT Join customfields cf1 ON cv1.customfieldid = cf1.customfieldid 
LEFT Join customfieldoptions co1 on cv1.fieldvalue = co1.customfieldoptionid 
WHERE t.dateline BETWEEN 1314853200 AND 1317445199 
Group by t.ticketid 
Order by t.Dateline asc;

Это основной запрос (без фильтрации) с 1 по 30 сентября. Время работы ~ 140 сек. Если убрать три линии соединения, время выполнения сокращается до ~ 0,01 сек.

SELECT * FROM tickets t 
LEFT Join customfieldvalues cv1 ON t.ticketid = cv1.typeid 
LEFT Join customfields cf1 ON cv1.customfieldid = cf1.customfieldid 
LEFT Join customfieldoptions co1 on cv1.fieldvalue = co1.customfieldoptionid 
LEFT Join customfieldvalues cv2 ON cv1.typeid = cv2.typeid
LEFT Join customfields cf2 ON cv2.customfieldid = cf2.customfieldid
LEFT Join customfieldoptions co2 on cv2.fieldvalue = co2.customfieldoptionid
WHERE t.dateline BETWEEN 1314853200 AND 1317445199 
AND cf1.title ='Customer Type'  AND co1.optionvalue = 'Staff' 
And cf2.title ='Building or Hall' AND co2.optionvalue like '%Stroupe%' 
Group by t.ticketid 
Order by t.Dateline asc;

Этот запрос будет основным запросом с двумя добавленными фильтрами: тип клиента (т.е. персонал) и местоположение здания или зала (Stroupe). При использовании того же периода времени, что и выше, время выполнения составляет ~ 0,1 сек.

==============================

РЕДАКТИРОВАТЬ: Здесь вывод команды EXPLAIN для первого запроса в списке.

INSERT INTO `table_name` (`id`,`select_type`,`table`,`type`,`possible_keys`,`key`,`key_len`,`ref`,`rows`,`Extra`) VALUES (1,'SIMPLE','t','range','tickets7','tickets7','4',NULL,601,'Using where; Using temporary; Using filesort');
INSERT INTO `table_name` (`id`,`select_type`,`table`,`type`,`possible_keys`,`key`,`key_len`,`ref`,`rows`,`Extra`) VALUES (1,'SIMPLE','cv1','ALL',NULL,NULL,NULL,NULL,104679,'');
INSERT INTO `table_name` (`id`,`select_type`,`table`,`type`,`possible_keys`,`key`,`key_len`,`ref`,`rows`,`Extra`) VALUES (1,'SIMPLE','cf1','eq_ref','PRIMARY','PRIMARY','4','DB.cv1.customfieldid',1,'');
INSERT INTO `table_name` (`id`,`select_type`,`table`,`type`,`possible_keys`,`key`,`key_len`,`ref`,`rows`,`Extra`) VALUES (1,'SIMPLE','co1','eq_ref','PRIMARY','PRIMARY','4','DB.cv1.fieldvalue',1,'');

Вот вывод EXPLAIN из второго запроса.

идентификатор, SELECT_TYPE, таблица, тип, possible_keys, ключ, key_len, реф, строки, Extra 1, SIMPLE, cf1, ref, "PRIMARY, title1", title1,767, const, 1, "Использование где; Использование временного; Использование сортировки файлов" 1, SIMPLE, co1, ref, "PRIMARY, optionvalue1", optionvalue1,767, const, 1, "Using where" 1, SIMPLE, cf2, ref, "PRIMARY, title1", title1,767, const, 1, "Using where" 1, ПРОСТОЙ, t, диапазон, «ПЕРВИЧНЫЙ, билеты7, билеты15, билеты16», билеты 7,4, ПУСТО (6), «Использование где» 1, SIMPLE, cv1, ref, customfieldvalues1, customfieldvalues1,8, "DB.cf1.customfieldid, DB.t.ticketid", 1, "Использование где" 1, SIMPLE, cv2, ref, customfieldvalues1, customfieldvalues1,8, "DB.cf2.customfieldid, DB.t.ticketid", 1, "Использование где" 1, SIMPLE, co2, eq_ref, PRIMARY, PRIMARY, 4, DB.cv2.fieldvalue, 1, «Using where»

1 Ответ

1 голос
/ 13 октября 2011

Это соединения, которые неправильны, ваше левое соединение + где условие = внутреннее соединение, вам нужно переписать запрос.

Вы говорите, что получите все строки из cf1, даже если они не существуют итолько те, которые имеют заголовок «Тип клиента».

Если вы измените левые объединения на внутренние, они будут более производительными (хотя могут и не возвращать то, что вы хотите)

...