mysql – 如何在使用count和group by时加快查询速度

我有两个名为seller和item的表.它们通过第三个表(seller_item)使用“n”到“m”外键关系连接.

现在我试着回答这个要求:“我作为卖家想要一份我的竞争对手的清单,其中包括我销售的商品数量以及他们的销售情况”.
因此,列出了与一个特定卖家相关的重叠项目数量的所有卖家.
此外,我希望按计数和有限排序.
但是查询使用临时表和文件输出非常慢.
说说:

用在哪里;使用索引;使用临时;使用filesort

我怎样才能加快速度呢?

这是查询:

SELECT
          COUNT(*) AS itemCount,
          s.sellerName
        FROM
          seller s,
          seller_item si
        WHERE
          si.itemId IN 
           (SELECT itemId FROM seller_item WHERE sellerId = 4711)
        AND
          si.sellerId=s.id
        GROUP BY
          sellerName
        ORDER BY
          itemCount DESC
        LIMIT 50;

表格defs:

CREATE TABLE `seller` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`sellerName` varchar(50) NOT NULL
PRIMARY KEY (`id`),
UNIQUE KEY `unique_index` (`sellerName`),
) ENGINE=InnoDB 

contains about 200.000 rows

CREATE TABLE `item` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`itemName` varchar(20) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `unique_index` (`itemName`),
) ENGINE=InnoDB

contains about 100.000.000 rows

CREATE TABLE `seller_item` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`sellerId` bigint(20) unsigned NOT NULL,
`itemId` bigint(20) unsigned NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `sellerId` (`sellerId`,`itemId`),
KEY `item_id` (`itemId`),
CONSTRAINT `fk_1` FOREIGN KEY (`sellerId`) REFERENCES `seller` (`id`)            ON DELETE CASCADE ON UPDATE NO ACTION,
CONSTRAINT `fk_2` FOREIGN KEY (`itemId`) REFERENCES `item` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB

contains about 170.000.000 rows

数据库是Mysql Percona 5.6

EXPLAIN的输出:

+----+-------------+-------------+--------+----------------------+-----    ---------+---------+---------------------+------+----------------------------------------------+
| id | select_type | table       | type   | possible_keys        | key                | key_len | ref                 | rows | Extra                                           |
+----+-------------+-------------+--------+----------------------+--------------+---------+---------------------+------+----------------------------------------------+
|  1 | SIMPLE      | s           | index  | PRIMARY,unique_index | unique_index | 152     | NULL                |    1 | Using index; Using temporary; Using filesort |
|  1 | SIMPLE      | si          | ref    | sellerId,item_id     | sellerId     | 8       | tmp.s.id            |    1 | Using index                                  |
|  1 | SIMPLE      | seller_item | eq_ref | sellerId,item_id     |  sellerId     | 16      | const,tmp.si.itemId |    1 | Using where; Using  index                     |
+----+-------------+-------------+--------+----------------------+--------------+---------+---------------------+------+----------------------------------------------+

解决方法:

我怀疑在你的大小的数据库上实现快速实时查询是可行的,特别是对于有大量热门商品库存的卖家.

你应该实现它.创建一个这样的表

CREATE TABLE
        matches
        (
        seller INT NOT NULL,
        competitor INT NOT NULL,
        matches INT NOT NULL,
        PRIMARY KEY
                (seller, competitor)
        )

并在cron脚本中批量更新它:

DELETE
FROM    matches
WHERE   seller = :seller

INSERT
INTO    matches (seller, competitor, matches)
SELECT  si.seller, sc.seller, COUNT(*) cnt
FROM    seller_item si
JOIN    seller_item sc
ON      sc.item = si.item
        AND sc.seller <> si.seller
WHERE   si.seller = :seller
GROUP BY
        si.seller, sc.seller
ORDER BY
        cnt DESC
LIMIT   50

您还需要在seller_item上制作(卖方,料品)PRIMARY KEY.现在的方式,按项目查找卖家需要两次查找而不是一次:首先使用KEY(item)逐项查找,然后使用PRIMARY KEY(id)按ID进行销售

上一篇:如何优化这个特定的MySQL查询,检查2.84M行和29.49k InnoDB不同的页面


下一篇:mysql – 在UTF8和Latin1表中将iso-8859-1数据转换为UTF-8