Задавайте вопросы, мы ответим
Вы не зашли.
Здраствуйте.
Есть таблица:
CREATE TABLE `data` ( `id` int(11) unsigned NOT NULL auto_increment, `uid` int(11) unsigned NOT NULL, `chr_string1` varchar(255) NOT NULL, `chr_string2` varchar(255) NOT NULL, `chr_string3` varchar(255) NOT NULL, `dec_value1` decimal(6,2) unsigned NOT NULL, `dec_value2` decimal(6,2) unsigned NOT NULL, `time` datetime NOT NULL, `boolen1` enum('0','1') NOT NULL default '1', PRIMARY KEY (`id`), KEY `time` (`time`), ) ENGINE=MyISAM DEFAULT CHARSET=cp1251;
в ней 100к записей.
И есть несколько запросов:
SELECT COUNT(*) as count, SUM(`dec_value1`) - SUM(`dec_value2`) as sum, DATE_FORMAT(`time`, '%e.%m.%Y') as time from data where uid = 1 and time BETWEEN STR_TO_DATE('$dstart', '%Y-%m-%d %H:%i:%s') and STR_TO_DATE('$dend', '%Y-%m-%d %H:%i:%s') and `boolen1` = '1' group by DATE_FORMAT(`time`, '%e%m%Y') order by time+0
22 rows in set (0.79 sec)
explain:
+----+-------------+-------+------+---------------+------+---------+------+-------+----------------------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+------+-------+----------------------------------------------+ | 1 | SIMPLE | data | ALL | time | NULL | NULL | NULL | 96885 | Using where; Using temporary; Using filesort | +----+-------------+-------+------+---------------+------+---------+------+-------+----------------------------------------------+
SELECT `chr_string1`, `chr_string2`, `chr_string3`, COUNT(*) as count, SUM(`dec_value1`) - SUM(`dec_value2`) as sum FROM data where uid = 1 and `chr_string1` <> '' and time BETWEEN STR_TO_DATE('$dstart', '%Y-%m-%d %H:%i:%s') and STR_TO_DATE('$dend', '%Y-%m-%d %H:%i:%s') and `boolen1` = '1' group by CONCAT(`chr_string1`, `chr_string2`, `chr_string3`) order by `chr_string1`, `chr_string2`, `chr_string3`+0 DESC
419 rows in set (0.93 sec)
explain:
+----+-------------+-------+------+---------------+------+---------+------+-------+----------------------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+------+-------+----------------------------------------------+ | 1 | SIMPLE | data | ALL | time | NULL | NULL | NULL | 96885 | Using where; Using temporary; Using filesort | +----+-------------+-------+------+---------------+------+---------+------+-------+----------------------------------------------+
В дальнейшем размер базы увеличится до порядка 1м записей.
Hard:
CPU: 2x xeon 3.0Ghz (двухядерных)
RAM: 2x 1Gb Kingston
HDD: Seagate 750Gb (sata)
Soft:
OS: CentOs 5.5
MySql: 5.0.91
Вопросы:
1. Нормальное ли это время для запросов?
2. Как правильно расставить индексы в данной таблице?
3. Как стоит перестроить запросы для лучшей производительности?
4. Где можно почитать толковые статьи по оптимизации (ссылки на печатные варианты приветствуются).
Заранее спасибо.
Неактивен
1. Нормальность времени определяется тем, удовлетворяет ли оно Вашим потребностям.
2. Я бы изменил индекс по времени на (uid, boolen1, time) — Так вы будете отсекать
данных куда больше по индексу.
3. От сортировки в памяти вряд ли избавишься, так как Вы группируете по очень стран-
ным выражениям.
4. Из книжек — есть хорошая книжка Барона.
Из онлайнового — есть хороший курс
Неактивен
CONCAT в группировке очень медленно работать будет, может вам лучше завести еще одно поле и писать туда MD5 от этих трёх полей, по этому полю можно будет создать ключ. это значительно должно облегчить выполнение запроса, особенно если вы планируете работать с миллионом записей. Еще несколько полезных советов по MySQL можете найти здесь WebDev.cz.cc
Неактивен