【问题标题】:Covering Index and two tables in mysql在mysql中覆盖索引和两个表
【发布时间】:2015-12-01 16:16:14
【问题描述】:

我有两个正在比较的表(NewProducts 和 OldProducts)。 NewProducts 有大约 68,000 条记录,OldProducts 大约有 51,000 条记录。我在每个表上都使用了覆盖索引,但是查询需要 20 分钟才能执行,所以我没有正确使用它。覆盖索引真的适用于多个表吗?我究竟做错了什么?谢谢。

这是我的查询代码和索引:

$querystring = "SELECT newProducts.Id, newProducts.SKU,
  newProducts.Title, oldProducts.Title, oldProducts.product_Id
        FROM
  newProducts, oldProducts
        WHERE
    trim(newProducts.SKU)=trim(oldProducts.SKU) and
    trim(newProducts.Title)=trim(oldProducts.Title) and
    oldProducts.Position=1 and
    oldProducts.Customer=$shop";


Indexes for NewProducts:
Primary: Id
Index:   SKU, Title, customer (not unique)

Indexes for OldProducts:
Primary: Id
Index: Product_id (not unique)
Index: SKU, Title, Postition, Customer (not unique)

?>

CREATE TABLE `NewProducts` (
`Id` bigint(11) NOT NULL,
`Title` varchar(120) COLLATE utf8_unicode_ci NOT NULL,
`Category` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`Office` varchar(150) COLLATE utf8_unicode_ci NOT NULL,
`Rehashed` smallint(6) NOT NULL,
`Quantity` smallint(6) NOT NULL,
`Price1` decimal(7,2) NOT NULL,
`Price2` decimal(7,2) NOT NULL,
`Price3` decimal(7,2) NOT NULL,
`Price4` decimal(7,2) NOT NULL,
`created_at` varchar(30) COLLATE utf8_unicode_ci DEFAULT NULL,
`OldQuantity` int(11) NOT NULL,
`SKU` varchar(55) COLLATE utf8_unicode_ci DEFAULT NULL,
`Source` varchar(12) COLLATE utf8_unicode_ci NOT NULL,
`customer` varchar(70) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`Id`),
UNIQUE KEY `I-T-S` (`ItemId`,`Title`,`SKU`),
KEY `customer` (`customer`),
KEY `Title` (`Title`,`Rehashed`),
KEY `SKU` (`SKU`),
KEY `Title_2` (`Title`,`SKU`,`customer`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci  

 CREATE TABLE `OldProducts` (
 `barcode` varchar(55) COLLATE utf8_unicode_ci DEFAULT NULL,
 `compare_at_price` decimal(10,2) DEFAULT NULL,
 `created_at` varchar(30) COLLATE utf8_unicode_ci DEFAULT NULL,
 `fulfillment` varchar(35) COLLATE utf8_unicode_ci DEFAULT NULL,
 `grams` decimal(10,2) DEFAULT NULL,
 `id` bigint(11) NOT NULL,
 `management` varchar(55) COLLATE utf8_unicode_ci DEFAULT NULL,
 `policy` varchar(55) COLLATE utf8_unicode_ci DEFAULT NULL,
 `size` varchar(55) COLLATE utf8_unicode_ci DEFAULT NULL,
 `color` varchar(55) COLLATE utf8_unicode_ci DEFAULT NULL,
 `type` varchar(55) COLLATE utf8_unicode_ci DEFAULT NULL,
 `position` int(11) DEFAULT NULL,
 `price` varchar(15) COLLATE utf8_unicode_ci DEFAULT NULL,
 `product_id` bigint(11) NOT NULL,
 `SKU` varchar(55) COLLATE utf8_unicode_ci DEFAULT NULL,
 `Title` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
 `quantity` int(11) DEFAULT NULL,
 `customer` varchar(70) COLLATE utf8_unicode_ci NOT NULL,
 PRIMARY KEY (`id`),
 UNIQUE KEY `P-S-T-PO-CUST`      
 (`product_id`,`SKU`,`Title`,`position`,`customer`),
 KEY `product_id` (`product_id`),

【问题讨论】:

  • 什么是 SKU?我不明白这个领域
  • 您应该展示您现有的表模式和CREATEd INDEXes,甚至可能展示内容摘录。还可以使用EXPLAIN 来显示查询计划。看来您应该清理存储的 ID 并使用真正的 JOIN 而不是 WHERE 子句映射。 (虽然我们的 SQL“人”通常可以推断出这样的事情,但如果你包含尽可能多的细节,它对未来的用户会更有用。)
  • 很难做到……显然,我在这里使用了别名。基本上一张表已经被转换为另一张表,我正在寻找匹配的记录来验证其他内容。它有效,但它比见鬼要慢,我显然正在努力加快速度。不同的是,每条记录不到 10,000 条,它的运行速度非常快。不知道为什么它在这里变慢。

标签: php mysql database optimization covering-index


【解决方案1】:

TRIM 是反派。当您在函数(例如,TRIM)中隐藏索引列(例如,SKU)时,该索引将无法使用。

清理您的数据:

  1. 在插入之前(或在插入时)将插入代码修复为 TRIM
  2. UPDATE tbl SET SKU = TRIM(SKU), title = TRIM(title); -- 每张桌子
  3. 更改SELECTTRIM(SKU) --> SKU

更好

oldProducts 应该有,按这个顺序

`INDEX(`position`,`customer` ,`SKU`,`Title`, `product_id`)

有了这个,WHERE 只需要查看old 行中的position=1 and customer =...。 (其实前2列可以任意排列,后3列任意排列。)

【讨论】:

  • 显示第 0 - 29 行(总共 47977 行,查询耗时 0.0020 秒)。枪的儿子....嗯,这有点快。谢谢先生,修剪确实是问题所在。
  • 谢谢。你是我的英雄。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-03
  • 1970-01-01
  • 2019-01-14
  • 2010-10-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多