mysql 中的覆盖索引和两个表
Covering Index and two tables in mysql
我有两个 table 正在比较(新产品和旧产品)。 NewProducts 有大约 68,000 条记录,OldProducts 有大约 51,000 条记录。我在每个 table 上使用覆盖索引,但是查询需要 20 分钟才能执行,所以我没有正确使用它。覆盖索引真的适用于多个 table 吗?我究竟做错了什么?谢谢。
这是我的查询代码和索引:
$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`),
TRIM
是反派。当您在函数(例如,TRIM
)中隐藏索引列(例如,SKU
)时,无法使用索引。
清理您的数据:
- 在插入之前(或插入时)将插入代码固定为
TRIM
。
UPDATE tbl SET SKU = TRIM(SKU), title = TRIM(title);
-- 对于每个 table
- 更改
SELECT
:TRIM(SKU)
--> SKU
等
更好
oldProducts
应该有,依次,
`INDEX(`position`,`customer` ,`SKU`,`Title`, `product_id`)
有了这个,WHERE
只需要查看 position=1 and customer =...
的 old
行。 (实际上,前 2 列可以任意排列;后 3 列任意排列。)
我有两个 table 正在比较(新产品和旧产品)。 NewProducts 有大约 68,000 条记录,OldProducts 有大约 51,000 条记录。我在每个 table 上使用覆盖索引,但是查询需要 20 分钟才能执行,所以我没有正确使用它。覆盖索引真的适用于多个 table 吗?我究竟做错了什么?谢谢。
这是我的查询代码和索引:
$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`),
TRIM
是反派。当您在函数(例如,TRIM
)中隐藏索引列(例如,SKU
)时,无法使用索引。
清理您的数据:
- 在插入之前(或插入时)将插入代码固定为
TRIM
。 UPDATE tbl SET SKU = TRIM(SKU), title = TRIM(title);
-- 对于每个 table- 更改
SELECT
:TRIM(SKU)
-->SKU
等
更好
oldProducts
应该有,依次,
`INDEX(`position`,`customer` ,`SKU`,`Title`, `product_id`)
有了这个,WHERE
只需要查看 position=1 and customer =...
的 old
行。 (实际上,前 2 列可以任意排列;后 3 列任意排列。)