MySQL 不同于子查询
MySQL Distinct from subQuery
移动到:MySQL Distinct performance
基本思路:
1) 我有一个有大量数据的 Mysql 服务器:
9 tables 以或多或少的线性方式与外键链接。
2) 我想通过 GUI 提取一些结果:
显示了这 9 个 table,每个 table 只有一个变量。让我们说:
- Table 1:频率:20,40,80,100
- Table 2:波长:300,400,500,600
- Table 3: ....
现在通过在 table->Frequency->20 中标记,数据库应该每隔 table 检查是否有使用 Freq 20 测量的条目并更新所有 tables取决于 20.
但是:我只想在每个 table 中显示不同的值。而这个 distinct 需要 17 秒,这对于 GUI 来说是非常糟糕的等待。
示例代码:
SELECT wafer.ID
FROM product
JOIN chip ON chip.product_name=product.name
JOIN wafer ON wafer.ID = chip.wafer_ID
JOIN lot ON lot.ID = wafer.lot_ID
JOIN ROI ON ROI.ID_string = chip.ROI_ID
JOIN result ON result.chip_ID = chip.ID_string
JOIN setup ON setup.ID_md5 = result.setup_ID
JOIN dataset ON dataset.ID_md5 = result.dataset_ID
WHERE product.name IN ("GoodProduct")
时长:0.34秒
获取:17 秒(1.5e6 行)
解释:
id, select_type, table, partitions, type, possible_keys, key, key_len, ref, rows, filtered, Extra
1 SIMPLE product const PRIMARY,name_UNIQUE PRIMARY 137 const 1 100.00 Using index
1 SIMPLE dataset index PRIMARY,ID_UNIQUE ID_UNIQUE 137 501 100.00 Using index
1 SIMPLE result ref dataset-result_idx,chip_ID_idx,setupID dataset-result_idx 137 databaseName.dataset.ID_md5 159 100.00
1 SIMPLE setup eq_ref PRIMARY PRIMARY 137 databaseName.result.setup_ID 1 100.00 Using index
1 SIMPLE chip eq_ref PRIMARY,ID_UNIQUE,Chip_UNIQUE,product_name_idx,ROI_ID PRIMARY 452 databaseName.result.chip_ID 1 49.99 Using where
1 SIMPLE ROI eq_ref PRIMARY,ID_UNIQUE PRIMARY 302 databaseName.chip.ROI_ID 1 100.00 Using index
1 SIMPLE wafer eq_ref PRIMARY,waferID_UNIQUE,number PRIMARY 62 databaseName.chip.wafer_ID 1 100.00
1 SIMPLE lot eq_ref PRIMARY,lotnumber_UNIQUE PRIMARY 62 databaseName.wafer.lot_ID 1 100.00 Using index
SELECT distinct wafer.ID {...same code as before}
时长:23秒
获取:0.000 秒(54 行)
解释:
id, select_type, table, partitions, type, possible_keys, key, key_len, ref, rows, filtered, Extra
1 SIMPLE product const PRIMARY,name_UNIQUE PRIMARY 137 const 1 100.00 Using index; Using temporary
1 SIMPLE dataset index PRIMARY,ID_UNIQUE ID_UNIQUE 137 501 100.00 Using index
1 SIMPLE result ref dataset-result_idx,chip_ID_idx,setupID dataset-result_idx 137 databaseName.dataset.ID_md5 159 100.00
1 SIMPLE setup eq_ref PRIMARY PRIMARY 137 databaseName.result.setup_ID 1 100.00 Using index
1 SIMPLE chip eq_ref PRIMARY,ID_UNIQUE,Chip_UNIQUE,product_name_idx,ROI_ID PRIMARY 452 databaseName.result.chip_ID 1 49.99 Using where
1 SIMPLE ROI eq_ref PRIMARY,ID_UNIQUE PRIMARY 302 databaseName.chip.ROI_ID 1 100.00 Using index
1 SIMPLE wafer eq_ref PRIMARY,waferID_UNIQUE,number PRIMARY 62 databaseName.chip.wafer_ID 1 100.00
1 SIMPLE lot eq_ref PRIMARY,lotnumber_UNIQUE PRIMARY 62 databaseName.wafer.lot_ID 1 100.00 Using index; Distinct
我真的很奇怪为什么这个 distinct 需要这么长时间。这里的所有行都有索引。
此示例仅显示一个 table 的代码。但是我需要 9 个更新 tables.
有什么方法可以加快这个过程或这个 "select distinct" 查询吗?
顺便说一句:我真的无法理解解释。如果有大提示我不会看的...
database
在询问查询性能问题时,您应该显示 tables 结构和索引,以便更容易提供帮助。
您要将 8 个 table 连接在一起,唯一的限制是产品名称必须是 "GoodProduct"
。 product
-table 与 product_name
相对 chip
连接在一起,因此您应该检查这些 name
/product_name
列上是否有索引.根据 ROI
和 result
中的行数,您可能需要对它们进行复合索引。
您的查询格式有点复杂,难以阅读。您可以使用格式简化事情:
SELECT wafer.ID
FROM product
JOIN chip ON chip.product_name=product.name
JOIN wafer ON wafer.ID = chip.wafer_ID
JOIN lot ON lot.ID = wafer.lot_ID
JOIN ROI ON ROI.ID_string = chip.ROI_ID
JOIN result ON result.chip_ID = chip.ID_string
JOIN setup ON setup.ID_md5 = result.setup_ID
JOIN dataset ON dataset.ID_md5 = result.dataset_ID
WHERE product.name IN ("GoodProduct")
请注意,tables lot
、ROI
、result
、setup
和 dataset
仅出于以下原因在查询中每个 table 上需要有一行与 "GoodProduct"
匹配。如果这不是必需的,您可以只使用 product
、chip
和 wafer
-tables 进行查询,性能会好得多。
这些表中的大多数都不能为查询提供任何证明。删除 lot
、dataset
甚至更多。 OTOH,他们 可能 提供的一件事是,例如,该项目是否有 "lot"。也就是说,这不会给你想要的答案吗?
SELECT DISTINCT wafer.ID
FROM product
JOIN chip ON chip.product_name = product.name
JOIN wafer ON wafer.ID = chip.wafer_ID
WHERE product.name IN ("GoodProduct")
如果您还没有这些索引,它们可能会有所帮助:
product: (name)
result: (dataset_ID, setup_ID, chip_ID)
dataset: (ID_md5)
setup: (ID_md5)
chip: (ID_string, ROI_ID, wafer_ID, product_name)
ROI: (ID_string)
wafer: (lot_ID, ID)
移动到:MySQL Distinct performance
基本思路:
1) 我有一个有大量数据的 Mysql 服务器: 9 tables 以或多或少的线性方式与外键链接。
2) 我想通过 GUI 提取一些结果: 显示了这 9 个 table,每个 table 只有一个变量。让我们说:
- Table 1:频率:20,40,80,100
- Table 2:波长:300,400,500,600
- Table 3: ....
现在通过在 table->Frequency->20 中标记,数据库应该每隔 table 检查是否有使用 Freq 20 测量的条目并更新所有 tables取决于 20.
但是:我只想在每个 table 中显示不同的值。而这个 distinct 需要 17 秒,这对于 GUI 来说是非常糟糕的等待。
示例代码:
SELECT wafer.ID
FROM product
JOIN chip ON chip.product_name=product.name
JOIN wafer ON wafer.ID = chip.wafer_ID
JOIN lot ON lot.ID = wafer.lot_ID
JOIN ROI ON ROI.ID_string = chip.ROI_ID
JOIN result ON result.chip_ID = chip.ID_string
JOIN setup ON setup.ID_md5 = result.setup_ID
JOIN dataset ON dataset.ID_md5 = result.dataset_ID
WHERE product.name IN ("GoodProduct")
时长:0.34秒 获取:17 秒(1.5e6 行)
解释:
id, select_type, table, partitions, type, possible_keys, key, key_len, ref, rows, filtered, Extra
1 SIMPLE product const PRIMARY,name_UNIQUE PRIMARY 137 const 1 100.00 Using index
1 SIMPLE dataset index PRIMARY,ID_UNIQUE ID_UNIQUE 137 501 100.00 Using index
1 SIMPLE result ref dataset-result_idx,chip_ID_idx,setupID dataset-result_idx 137 databaseName.dataset.ID_md5 159 100.00
1 SIMPLE setup eq_ref PRIMARY PRIMARY 137 databaseName.result.setup_ID 1 100.00 Using index
1 SIMPLE chip eq_ref PRIMARY,ID_UNIQUE,Chip_UNIQUE,product_name_idx,ROI_ID PRIMARY 452 databaseName.result.chip_ID 1 49.99 Using where
1 SIMPLE ROI eq_ref PRIMARY,ID_UNIQUE PRIMARY 302 databaseName.chip.ROI_ID 1 100.00 Using index
1 SIMPLE wafer eq_ref PRIMARY,waferID_UNIQUE,number PRIMARY 62 databaseName.chip.wafer_ID 1 100.00
1 SIMPLE lot eq_ref PRIMARY,lotnumber_UNIQUE PRIMARY 62 databaseName.wafer.lot_ID 1 100.00 Using index
SELECT distinct wafer.ID {...same code as before}
时长:23秒 获取:0.000 秒(54 行)
解释:
id, select_type, table, partitions, type, possible_keys, key, key_len, ref, rows, filtered, Extra
1 SIMPLE product const PRIMARY,name_UNIQUE PRIMARY 137 const 1 100.00 Using index; Using temporary
1 SIMPLE dataset index PRIMARY,ID_UNIQUE ID_UNIQUE 137 501 100.00 Using index
1 SIMPLE result ref dataset-result_idx,chip_ID_idx,setupID dataset-result_idx 137 databaseName.dataset.ID_md5 159 100.00
1 SIMPLE setup eq_ref PRIMARY PRIMARY 137 databaseName.result.setup_ID 1 100.00 Using index
1 SIMPLE chip eq_ref PRIMARY,ID_UNIQUE,Chip_UNIQUE,product_name_idx,ROI_ID PRIMARY 452 databaseName.result.chip_ID 1 49.99 Using where
1 SIMPLE ROI eq_ref PRIMARY,ID_UNIQUE PRIMARY 302 databaseName.chip.ROI_ID 1 100.00 Using index
1 SIMPLE wafer eq_ref PRIMARY,waferID_UNIQUE,number PRIMARY 62 databaseName.chip.wafer_ID 1 100.00
1 SIMPLE lot eq_ref PRIMARY,lotnumber_UNIQUE PRIMARY 62 databaseName.wafer.lot_ID 1 100.00 Using index; Distinct
我真的很奇怪为什么这个 distinct 需要这么长时间。这里的所有行都有索引。 此示例仅显示一个 table 的代码。但是我需要 9 个更新 tables.
有什么方法可以加快这个过程或这个 "select distinct" 查询吗?
顺便说一句:我真的无法理解解释。如果有大提示我不会看的...
database
在询问查询性能问题时,您应该显示 tables 结构和索引,以便更容易提供帮助。
您要将 8 个 table 连接在一起,唯一的限制是产品名称必须是 "GoodProduct"
。 product
-table 与 product_name
相对 chip
连接在一起,因此您应该检查这些 name
/product_name
列上是否有索引.根据 ROI
和 result
中的行数,您可能需要对它们进行复合索引。
您的查询格式有点复杂,难以阅读。您可以使用格式简化事情:
SELECT wafer.ID
FROM product
JOIN chip ON chip.product_name=product.name
JOIN wafer ON wafer.ID = chip.wafer_ID
JOIN lot ON lot.ID = wafer.lot_ID
JOIN ROI ON ROI.ID_string = chip.ROI_ID
JOIN result ON result.chip_ID = chip.ID_string
JOIN setup ON setup.ID_md5 = result.setup_ID
JOIN dataset ON dataset.ID_md5 = result.dataset_ID
WHERE product.name IN ("GoodProduct")
请注意,tables lot
、ROI
、result
、setup
和 dataset
仅出于以下原因在查询中每个 table 上需要有一行与 "GoodProduct"
匹配。如果这不是必需的,您可以只使用 product
、chip
和 wafer
-tables 进行查询,性能会好得多。
这些表中的大多数都不能为查询提供任何证明。删除 lot
、dataset
甚至更多。 OTOH,他们 可能 提供的一件事是,例如,该项目是否有 "lot"。也就是说,这不会给你想要的答案吗?
SELECT DISTINCT wafer.ID
FROM product
JOIN chip ON chip.product_name = product.name
JOIN wafer ON wafer.ID = chip.wafer_ID
WHERE product.name IN ("GoodProduct")
如果您还没有这些索引,它们可能会有所帮助:
product: (name)
result: (dataset_ID, setup_ID, chip_ID)
dataset: (ID_md5)
setup: (ID_md5)
chip: (ID_string, ROI_ID, wafer_ID, product_name)
ROI: (ID_string)
wafer: (lot_ID, ID)