2010-11-23 5 views
2

У меня трудное время получить лучшие результаты по данному запросу:трудного времени оптимизация запроса

Я следующие 2 таблиц:

DROP TABLE IF EXISTS `casino`.`mutualfriends`; 
CREATE TABLE `casino`.`mutualfriends` (
    `CustUID` varchar(64) CHARACTER SET ascii NOT NULL, 
    `CustUID2` varchar(64) CHARACTER SET ascii NOT NULL, 
    `FType` tinyint(4) NOT NULL, 
    PRIMARY KEY (`CustUID`,`CustUID2`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8; 


DROP TABLE IF EXISTS `casino`.`customers`; 
CREATE TABLE `casino`.`customers` (
    `CustFullName` varchar(45) NOT NULL, 
    `CustEmail` varchar(128) NOT NULL, 
    `CustUID` varchar(64) CHARACTER SET ascii NOT NULL, 
    `CustMoney` bigint(20) NOT NULL DEFAULT '0', 
    `SmallPicURL` varchar(120) CHARACTER SET ascii DEFAULT '', 
    `LargePicURL` varchar(120) CHARACTER SET ascii DEFAULT '', 
    PRIMARY KEY (`CustUID`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

В таблице клиентов уже 1M ряды, общие друзья есть 500K строк.

Мне сложно оптимизировать этот запрос; похоже, что с ним используется сканирование таблицы. Я хотел бы, чтобы свести к минимуму сканирования:

SELECT c.CustUID AS Cuid, c.CustFullName, c.CustMoney, c.SmallPicURL 
FROM `customers` c 
WHERE c.`CustUID` = '1:1542073175' 
UNION 
SELECT m.`CustUID2` AS Cuid, c.CustFullName, c.CustMoney, c.SmallPicURL 
FROM `mutualfriends` m, `customers` c 
WHERE m.`CustUID` = '1:1542073175' 
AND c.`CustUID` = m.`CustUID2` 
UNION 
SELECT m.`CustUID` AS Cuid, c.CustFullName, c.CustMoney, c.SmallPicURL 
FROM `mutualfriends` m, customers c 
WHERE m.`CustUID2` = '1:1542073175' 
AND c.CustUID = m.`CustUID` 
+0

Что именно вы пытаетесь сделать? Вы пытаетесь получить список всех клиентов и их общих друзей? Это не совсем понятно из вашего кода. – Ramy 2010-11-23 05:54:02

+0

Ну, что я делаю, получается список клиентов, которые являются общими друзьями с клиентом, который его id: «1: 1542073175». результаты запроса правильные, но его производительность плохая, я ищу способ получить те же результаты, что и выше, но с лучшей производительностью – mysqldude 2010-11-23 05:57:17

ответ

2

Я думаю, вам нужен индекс MutualFriends.CustUID2 (индекс дублей, а не уникальный индекс, а не как часть первичный ключ). Первичный ключ, вероятно, дает вам полезный индекс для запросов, в которых указан первый клиент («1: 1542073175»).

Проверьте объяснение плана запроса.

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

0

попробовать этот запрос

SELECT c.CustUID AS Cuid, c.CustFullName, c.CustMoney, c.SmallPicURL 
FROM `customers` c INNER JOIN `mutualfriends` m 
IN c.CustUID = m.`CustUID` 
WHERE m.`CustUID2` = '1:1542073175' 
+0

спасибо за ответ, он не дает те же результаты, что и мой запрос, строк, любых идей? – mysqldude 2010-11-23 06:04:00

+1

Запрос не выбирается должным образом. Если у клиента нет общих друзей, то ничего не выбрано; если клиент не является общим другом с самим собой, тогда ничего не выбрано; он не выбирает строки, где клиент является основным другом кого-то другого; и т. д. – 2010-11-23 06:15:16

0

Попробуйте с этим запросом:

select * 
from customers 
where CustUID in (
    select CustUID 
    from mutual_friends 
    where CustUID2 = '1:1542073175' 
    union all 
    select CustUID2 
    from mutual_friends 
    where CustUID = '1:1542073175' 
    union all 
    select '1:1542073175' 
) 

Это быстрее?

Смежные вопросы