【发布时间】:2011-05-13 03:41:39
【问题描述】:
我很茫然。我有一个大约 100K 行的表。查询这张表的时候结果通常比较快,大概2ms左右。但是每当我使用 ORDER BY 时,性能就会像石头一样下降到大约 120 毫秒。我阅读了MySQL ORDER BY Optimization 页面,但我不能说我了解所有内容。尤其是索引我不清楚。
最终我想运行以下查询:
SELECT *
FROM `affiliate_new_contracts`
WHERE phone_brand IN ('Apple','Blackberry','HTC','LG','Motorola','Nokia',
'Samsung','Sony Ericsson')
AND contract_length IN ('12','24')
AND (addon IS NULL OR addon IN('Telfort Sms 300','Surf & Mail'))
AND (plan_name = 'Telfort 100'
AND
credible_shop = 1
)
ORDER BY average_price_per_month ASC, phone_price_guestimate DESC,
contract_length ASC;
但如果我了解基本原则,我会很高兴。
删除上一个查询中的 ORDER BY 子句使其在 20 毫秒而不是 120 毫秒内运行。我在 average_price_per_month 字段上有一个索引,但将 ORDER BY 子句简化为 ORDER BY average_price_per_month 并没有提高性能。我不明白。我也对所谓的多列索引一无所知,它应该能够帮助我进行最终查询。
任何帮助将不胜感激。如何让这个坏男孩表演?还是那个追求乌托邦?
CREATE TABLE 语法如下:
$ show create table affiliate_new_contracts;
CREATE TABLE `affiliate_new_contracts` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`plan_name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`contract_length` int(11) DEFAULT NULL,
`phone_brand` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`price` float DEFAULT NULL,
`average_price_per_month` float DEFAULT NULL,
`phone_price_guestimate` float DEFAULT NULL,
`credible_shop` tinyint(1) DEFAULT '0',
`addon` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`addon_price` float DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `index_affiliate_new_contracts_on_plan_name` (`plan_name`),
KEY `index_affiliate_new_contracts_on_average_price_per_month` (`average_price_per_month`),
KEY `index_affiliate_new_contracts_on_price` (`price`)
) ENGINE=InnoDB AUTO_INCREMENT=2472311 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
顺便说一句,此表每周重新创建,同时不会更新。
【问题讨论】:
-
我重新格式化查询以避免水平滚动条。最后几个查询术语(关于计划名称和可信商店)与查询的其余部分不一致(其他术语不使用表名)并且实际上不需要它们周围的括号。我争论是否在不发表评论的情况下修复它......并决定不这样做。如果您决定使这些条款保持一致,我将删除此评论。
-
优秀的评论。部分查询已生成/已生成(更多证据表明我不太适合查询)。我删除了多余的表名。
标签: mysql optimization query-optimization sql-order-by