【发布时间】:2013-06-04 12:48:33
【问题描述】:
我有两张桌子:
类别
category_id int(10) UNSIGNED AUTO_INCREMENT
category_title varchar(255)
产品
product_id int(10) UNSIGNED AUTO_INCREMENT
product_category int(10) UNSIGNED
product_title varchar(255)
列product_category 是与category_id 相关的外键。这是一些数据:
category_id category_title
----------- --------------
3 Cellphone
4 Motherboard
5 Monitor
product_id product_category product_title
---------- ---------------- -------------
3 3 Samsung Galaxy SIII
4 3 Apple iPhone 5
5 3 HTC One X
如何通过产品数量获取所有类别?
category_id category_title products_count
----------- -------------- --------------
3 Cellphone 3
4 Motherboard 9
5 Monitor 7
我使用了这个查询:
SELECT
`category_id` AS `id`,
`category_title` AS `title`,
COUNT( `product_id` ) AS `count`
FROM `ws_shop_category`
LEFT OUTER JOIN `ws_shop_product`
ON `product_category` = `category_id`
GROUP BY `category_id`
ORDER BY `title` ASC
但耗时太长:(总共 254 个,查询耗时 4.4019 秒)。 我怎样才能使这个查询更好?
DESC
在查询前添加DESC,给我这个结果:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE ws_shop_category ALL NULL NULL NULL NULL 255 Using temporary; Using filesort
1 SIMPLE ws_shop_product ALL NULL NULL NULL NULL 14320
显示创建表
CREATE TABLE `ws_shop_product` (
`product_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`product_category` int(10) unsigned DEFAULT NULL,
`product_title` varchar(255) COLLATE utf8_general_ci DEFAULT NULL,
PRIMARY KEY (`product_id`)
) ENGINE=MyISAM AUTO_INCREMENT=14499 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
CREATE TABLE `ws_shop_category` (
`category_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`category_title` varchar(255) COLLATE utf8_general_ci DEFAULT NULL,
PRIMARY KEY (`category_id`)
) ENGINE=MyISAM AUTO_INCREMENT=260 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
【问题讨论】:
-
为什么你使用左外连接而不是内连接?这显然会减慢查询速度。更不用说它甚至会计算那些没有匹配的人。
-
您是如何定义表上的索引的?慢查询通常表明没有使用索引。您可以通过在查询开头添加
DESC并执行它来查看查询计划。 -
@Edper 是的,内连接给了我一个快速的结果,但我对没有产品的类别使用了左外连接(计数 = 0)。
-
@ErikSchierboom 我在查询之前添加了
DESC的结果。 -
@user2450111 是的,这表明没有使用索引。我会尽快发布并回复。
标签: mysql sql performance