2012-06-30 3 views
2

У меня есть следующая таблица с миллионами строк:Mysql медленно Perfomance на большом столе

CREATE TABLE `points` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `DateNumber` int(10) unsigned DEFAULT NULL, 
    `Count` int(10) unsigned DEFAULT NULL, 
    `FPTKeyId` int(10) unsigned DEFAULT NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `id_UNIQUE` (`id`), 
    KEY `index3` (`FPTKeyId`,`DateNumber`) USING HASH 
) ENGINE=InnoDB AUTO_INCREMENT=16755134 DEFAULT CHARSET=utf8$$ 

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

Давайте возьмем простой запрос,

SELECT fptkeyid, count FROM points group by fptkeyid 

Я cannt получить результат, потому что запрос прерывания по таймауту (10 мин). Что я делаю неправильно?

+1

Примечание: «PRIMARY KEY» всегда уникален по умолчанию, поэтому «UNIQUE KEY (id)», вероятно, не нужен. – biziclop

+0

Я искал 'mysql group, не используя индекс', и нашел это приятное, долгое чтение: http://dev.mysql.com/doc/refman/5.0/ru/group-by-optimization.html – biziclop

+0

. чтобы мы могли ответить на вопрос. Покажите несколько примеров строк, объяснение запроса, общее представление об оборудовании и некоторые измерения, сделанные вами перед публикацией. Таким образом, вы получите более конкретные ответы, которые подходят для вашей ситуации. –

ответ

-1

Я думаю, что проблема заключается в пропускной способности вашего сервера. Имея миллион строк, вероятно, потребуется, по крайней мере, мегабайт пропускной способности.

+0

im выполнение запроса на моей локальной машине – Neir0

3

Остерегайтесь глупого поведения MySQL: GROUP BY ing неявно выполняет ORDER BY.

Чтобы предотвратить это, явно добавьте ORDER BY NULL, что предотвратит ненужный порядок.

http://dev.mysql.com/doc/refman/5.0/en/select.html говорит:

При использовании GROUP BY, выходные строки сортируются в соответствии с GROUP BY колонн, как если бы вы имели ORDER BY для тех же столбцов. Для того, чтобы избежать накладных расходов сортировки, что GROUP BY производит, добавить ORDER BY NULL:

SELECT a, COUNT(b) FROM test_table GROUP BY a ORDER BY NULL; 

+

http://dev.mysql.com/doc/refman/5.6/en/group-by-optimization.html говорит:

Наиболее важные предпосылки для использования индексов для GROUP BY , что все столбцы GROUP BY ссылаются на атрибуты из того же индекса, и что индекс сохраняет свои ключи в порядке (например, это BTREE индекс, а не HASH индекс).

+0

к сожалению, он все еще работает медленным – Neir0

+0

577 сек. Для этого запроса – Neir0

+0

@ Neir0 Ну, если у вас много миллионов строк, mysql должен пройти через каждый из них, t есть какое-либо предложение where в запросе. Это требует времени. Возможно, вам понадобится сводная таблица, сохраняющая эти агрегаты, если вам нужно часто запускать такие запросы, как эта. – nos

1

Я бы лично начал с вашего значения AUTO_INCREMENT. Вы установили его на увеличение на 16,755,134 за каждую новую запись. Значение вашего поля установлено на INT UNSIGNED, что означает, что диапазон значений составляет 0 to 4,294,967,295 (или почти 4,3 миллиарда). Это означает, что у вас было бы только 256 значения, прежде чем поле выходит за пределы ограничений типа данных, тем самым ставя под угрозу цель PRIMARY KEY INDEX.

Вы могли бы изменил тип данных BIGINT UNSIGNED и вы бы диапазон значений 0 to 18,446,744,073,709,551,615 (или чуть более 18,4 квинтильонов), который позволит вам иметь до 1,100,960,700,983 (или чуть более 1,1 трлн) уникальных значений с этим значением AUTO_INCREMENT.

Я бы сначала спросить, если вам действительно нужно иметь ваше значение AUTO_INCREMENT устанавливается в таком большом количестве, и если нет, то я бы предложить изменения, которые до 1 (или, по крайней мере, некоторого меньшего числа) в качестве сохранения значения полей INT vs BIGINT сохранит значительное дисковое пространство в больших таблицах, таких как это. В любом случае, вы должны получить более стабильный PRIMARY KEY INDEX, который должен помочь улучшить запросы.

1

Ваш запрос не имеет смысла:

SELECT fptkeyid, count FROM points group by fptkeyid 

Вы группа по fptkeyid так рассчитывать не полезно здесь. Должна быть агрегатная функция. Не поле счета. Далее, что это число также является функцией MySQL, что делает его не очень полезным/целесообразным использовать одно и то же имя для поля.

Вам не нужно что-то вроде:

SELECT fptkeyid, SUM(`count`) FROM points group by fptkeyid 

Если нет, пожалуйста, объясните какой результат вы ожидаете от запроса.

Создана база данных с данными испытаний, полмиллиона записей, чтобы узнать, могу ли я найти что-то равное вашей проблеме. Это то, что говорит мне объяснить:

id select_type table type possible_keys key key_len ref rows Extra 
1 SIMPLE points index NULL index3 10 NULL 433756 

А на запрос SUM:

id select_type table type possible_keys key key_len ref rows Extra 
1 SIMPLE points index NULL index3 10 NULL 491781 

Оба запроса выполняются на ноутбуке (Macbook Air) в секунду, ничего не занимает много времени. Вставка, хотя и заняла некоторое время, несколько минут, чтобы получить полмиллиона записей. Но извлечения и вычисления не происходит.

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

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