MySQL查询在大数据上的速度非常慢
我不是MySQL高手,但我明白了,我刚刚继承了一个相当大的表(600000行和大约90列(请杀了我…),我创建了一个较小的表,将它与一个categories表链接起来 我试图用一个左连接查询所说的表,所以我在一个对象中有两组数据,但它运行得非常慢,我没有足够的热量来排序它;我真的很想得到一些指导和解释,解释一下为什么它这么慢MySQL查询在大数据上的速度非常慢,mysql,pdo,Mysql,Pdo,我不是MySQL高手,但我明白了,我刚刚继承了一个相当大的表(600000行和大约90列(请杀了我…),我创建了一个较小的表,将它与一个categories表链接起来 我试图用一个左连接查询所说的表,所以我在一个对象中有两组数据,但它运行得非常慢,我没有足够的热量来排序它;我真的很想得到一些指导和解释,解释一下为什么它这么慢 SELECT `products`.`Product_number`, `products`.`Price`, `products`.`Previ
SELECT
`products`.`Product_number`,
`products`.`Price`,
`products`.`Previous_Price_1`,
`products`.`Previous_Price_2`,
`products`.`Product_number`,
`products`.`AverageOverallRating`,
`products`.`Name`,
`products`.`Brand_description`
FROM `product_categories`
LEFT OUTER JOIN `products`
ON `products`.`product_id`= `product_categories`.`product_id`
WHERE COALESCE(product_categories.cat4, product_categories.cat3,
product_categories.cat2, product_categories.cat1) = '123456'
AND `product_categories`.`product_id` != 0
这两个表是MyISAM,products表对Product_number和Brand_Description进行了索引,Product_categories表对组合的所有列进行了唯一索引;如果这个信息有任何帮助
继承了这个系统之后,我需要在我使用核武器之前尽快让它工作起来,并正确地使用它,所以现在的任何帮助都将赢得我最大的尊重
[编辑]
以下是explain extended的输出:
+----+-------------+--------------------+-------+---------------+------+---------+------+---------+----------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------------------+-------+---------------+------+---------+------+---------+----------+--------------------------+
| 1 | SIMPLE | product_categories | index | NULL | cat1 | 23 | NULL | 1224419 | 100.00 | Using where; Using index |
| 1 | SIMPLE | products | ALL | Product_id | NULL | NULL | NULL | 512376 | 100.00 | |
+----+-------------+--------------------+-------+---------------+------+---------+------+---------+----------+--------------------------+
优化表
为了建立一个基线,我首先建议在两个表上运行一个命令。请注意,这可能需要一些时间。从:
如果删除了一个表的大部分,则应使用优化表
表,或者如果您对具有可变长度的表进行了多次更改
行(具有VARCHAR、VARBINARY、BLOB
或TEXT
列的表)。
已删除的行保存在链表中,后续的INSERT
操作重用旧的行位置。您可以使用优化表
来
回收未使用的空间并对数据文件进行碎片整理。之后
对表进行大量更改,此语句也可能会有所改进
使用表格的语句的性能,有时非常重要。
[……]
对于MyISAM表,优化表
的工作原理如下:
产品类别
的cat1
索引。这很可能只包括cat1
列。通过将所有四个类别列添加到索引中,它可以更有效地查找所需的行。从:
MySQL可以使用多个列索引进行查询,以测试所有
索引中的列,或仅测试第一列的查询
前两列、前三列,依此类推。如果您指定
索引定义中顺序正确的列,单个
复合索引可以加速对同一数据库的多种查询
桌子
结构
此外,考虑到您的表有90列,您还应该意识到这一点。您可能需要将表考虑到多个表:
列太多可能会使记录的大小膨胀,从而
导致更多内存块被读入和读出内存,从而导致
较高的I/O。这可能会影响性能。解决这个问题的一个办法是
将表拆分为更小、更独立的表,并使用更小的
基数大于原始基数。现在,这应该允许更好的解决方案
阻塞因子(如上定义),这意味着更少的I/O和更快的速度
性能。像这样把桌子拆开的过程是一个复杂的过程
称为垂直分区
优化表
为了建立一个基线,我首先建议在两个表上运行一个命令。请注意,这可能需要一些时间。从:
如果删除了一个表的大部分,则应使用优化表
表,或者如果您对具有可变长度的表进行了多次更改
行(具有VARCHAR、VARBINARY、BLOB
或TEXT
列的表)。
已删除的行保存在链表中,后续的INSERT
操作重用旧的行位置。您可以使用优化表
来
回收未使用的空间并对数据文件进行碎片整理。之后
对表进行大量更改,此语句也可能会有所改进
使用表格的语句的性能,有时非常重要。
[……]
对于MyISAM表,优化表
的工作原理如下:
产品类别
的cat1
索引。这很可能只包括cat1
列。通过将所有四个类别列添加到索引中,它可以更有效地查找所需的行。从:
MySQL可以使用多个列索引进行查询,以测试所有
索引中的列,或仅测试第一列的查询
前两列、前三列,依此类推。如果您指定
索引定义中顺序正确的列,单个
复合索引可以加速对同一数据库的多种查询
桌子
结构
此外,考虑到您的表有90列,您还应该意识到这一点。您可能需要将表考虑到多个表:
列太多会导致记录大小膨胀,我认为
product_categories.cat4, product_categories.cat3, product_categories.cat2, product_categories.cat1
FROM `product_categories` pc
LEFT OUTER JOIN `products` p ON p.category_id = pc.id
WHERE
COALESCE(product_categories.cat4, product_categories.cat3,product_categories.cat2, product_categories.cat1) = '123456'
AND pc.id != 0
SELECT /* some columns from the products table */
FROM products
WHERE product_id IN
(
SELECT DISTINCT product_id
FROM product_categories
WHERE product_id <> 0
AND ( cat1='123456'
OR cat2='123456'
OR cat3='123456'
OR cat4='123456')
)
SELECT /* some columns from the products table */
FROM products
WHERE product_id IN
(
SELECT product_id
FROM product_categories
WHERE MATCH(cat1,cat2,cat3,cat4)
AGAINST('123456' IN BOOLEAN MODE)
AND product_id <> 0
)
CREATE FULLTEXT INDEX cat_lookup
ON product_categories (cat1, cat2, cat3, cat4)
cat1 cat2 cat3 cat4
123451 123453 123455 123456 matches your and my queries
123456 123455 123454 123452 matches my queries but not yours