2016-09-14 5 views
0

я следующие 2 одинаковые таблицы, используя MySQL:MySQL MyISAM Разница в поле Count между двумя одинаковыми таблицами

DROP TABLE IF EXISTS `DB`.`tblNew`; 
CREATE TABLE `DB`.`tblNew` (
`NumberPK` int(10) unsigned NOT NULL, 
`Count` int(10) unsigned NOT NULL, 
PRIMARY KEY (`NumberPK`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1; 

и

DROP TABLE IF EXISTS `DB`.`tblPrev`; 
CREATE TABLE `DB`.`tblPrev` (
`NumberPK` int(10) unsigned NOT NULL, 
`Count` int(10) unsigned NOT NULL, 
PRIMARY KEY (`NumberPK`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1; 

Я хочу, чтобы получить разницу в «Count» поле между двумя таблицами, основанное на их присоединении к полю «NumberPK».

Я написал этот вопрос:

SELECT 
gvNew.NumberPK 
FROM 
tblNew AS gvNew 
LEFT OUTER JOIN 
tblPrev AS gvPrev ON gvNew.NumberPK = gvPrev.NumberPK 
ORDER BY gvNew.Count - IFNULL(gvPrev.Count, 0) DESC 
LIMIT 10 

для того, чтобы получить 10 «NumberPK» записи, где разница была наибольшей.

Проблема заключается в том, что MySql должен выполнить сканирование таблицы, чтобы получить разницу в Counts. Соединение очень эффективно, так как оно находится на первичном ключе и, хотя с примерно 50000 записями, результаты возвращаются почти мгновенно, мне интересно, будет ли сканирование (по таблицам с двумя 4-байтовыми полями в каждом) так же быстро, с таблицами между 1-4 миллионами строк.

Или, есть ли лучшие способы сделать это?

Спасибо заранее, Tim

+0

Вам нужно учитывать, где разница отрицательная? –

+0

Привет @ P.Salmon ... нет разницы никогда не может быть отрицательным ... это может быть 0, но не отрицательно. – user3480610

ответ

0

Использования PRIMARY KEY в MyISAM так же, как с помощью любого другого индекса: Детализация индекса ВТКЕЯ, а затем сделать случайный поиск в данные.

В вашем случае вам нужно сканировать все строки в в начале таблицы, так как вы не можете предсказать, какой из них будет представлять интерес. Затем найдите каждую строку в другой таблице, так как вы не можете сказать, какой из 10 будет необходим.

Имея INDEX(NumberPK, Count), вы избежите дополнительного шага, упомянутого выше. Добавьте это в обе таблицы, так как вы не можете предсказать, какой порядок оптимизатор попадет в таблицы. (С помощью InnoDB кластеризация ПК сделает этот индекс избыточным.)

Альтернативно ... Вот еще одна возможность.

SELECT NumberPk, MAX(`Count`) - MIN(`Count`) AS diff 
    FROM (
    SELECT * FROM tblNew 
    UNION ALL 
    SELECT * FROM tblPrev 
) X 
    GROUP BY NumberPk 
    ORDER BY diff DESC 
    LIMIT 10 

Это избавляет от всех поисков, но добавляет их в большом виде. Поэтому я не могу предсказать, будет ли это быстрее.

+0

Привет, спасибо за ваш ответ. Я сбросил PK на NumberPK и добавил указанный индекс в обе таблицы. Кажется, что запрос выполняется в два раза быстрее, но я пропущу некоторое время, чтобы получить больше данных и более значимые результаты. Спасибо за вашу идею! – user3480610

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