Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql:选择id,然后在id上选择*比选择*快得多。为什么?_Mysql_Query Optimization - Fatal编程技术网

Mysql:选择id,然后在id上选择*比选择*快得多。为什么?

Mysql:选择id,然后在id上选择*比选择*快得多。为什么?,mysql,query-optimization,Mysql,Query Optimization,我有一个MySQL数据库表(大约10万行): id BIGINT(索引)、外部条形码VARCHAR(索引)、其他简单列和长文本列 LongText列是一个JSON数据转储。我保存大型JSON对象,因为将来需要提取更多数据 运行此查询需要29秒以上的时间: SELECT * FROM scraper_data WHERE external_barcode = '032429257284' 说明 #id select_type table partitions type po

我有一个MySQL数据库表(大约10万行):

id BIGINT(索引)、外部条形码VARCHAR(索引)、其他简单列和长文本列

LongText列是一个JSON数据转储。我保存大型JSON对象,因为将来需要提取更多数据

运行此查询需要29秒以上的时间:

SELECT * FROM scraper_data WHERE external_barcode = '032429257284'
说明

#id  select_type table          partitions type  possible_keys key  key_len ref  rows     filtered Extra
'1' 'SIMPLE'     'scraper_data' NULL       'ALL' NULL          NULL NULL    NULL '119902' '0.00'   'Using where'
# id, select_type, table, partitions, type, possible_keys, key, key_len, ref, rows, filtered, Extra
'1', 'PRIMARY', 'scraper_data', NULL, 'const', 'PRIMARY,id_UNIQUE', 'PRIMARY', '8', 'const', '1', '100.00', NULL
'2', 'SUBQUERY', 'scraper_data', NULL, 'ALL', NULL, NULL, NULL, NULL, '119902', '0.00', 'Using where'
此更复杂的查询需要0.00秒:

SELECT * FROM scraper_data WHERE id = (
    SELECT id FROM scraper_data WHERE external_barcode = '032429257284'
)
说明

#id  select_type table          partitions type  possible_keys key  key_len ref  rows     filtered Extra
'1' 'SIMPLE'     'scraper_data' NULL       'ALL' NULL          NULL NULL    NULL '119902' '0.00'   'Using where'
# id, select_type, table, partitions, type, possible_keys, key, key_len, ref, rows, filtered, Extra
'1', 'PRIMARY', 'scraper_data', NULL, 'const', 'PRIMARY,id_UNIQUE', 'PRIMARY', '8', 'const', '1', '100.00', NULL
'2', 'SUBQUERY', 'scraper_data', NULL, 'ALL', NULL, NULL, NULL, NULL, '119902', '0.00', 'Using where'
从这些查询返回的行少于6行。既然where子句中没有引用第一个查询,为什么长文本会减慢第一个查询的速度

创建表

CREATE TABLE `scraper_data` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `bzic` varchar(10) NOT NULL,
  `pzic` varchar(10) DEFAULT NULL,
  `internal_barcode` varchar(20) DEFAULT NULL,
  `external_barcode_type` enum('upc','isbn','ean','gtin') DEFAULT NULL,
  `external_barcode` varchar(15) DEFAULT NULL,
  `url` varchar(255) NOT NULL,
  `title` varchar(255) DEFAULT NULL,
  `category` varchar(3) DEFAULT NULL,
  `description` text,
  `logo_image_url` varchar(255) DEFAULT NULL,
  `variant_image_urls` text,
  `parent_brand` varchar(10) DEFAULT NULL,
  `parent_brand_name` varchar(255) DEFAULT NULL,
  `manufacturer` varchar(10) DEFAULT NULL,
  `manufacturer_name` varchar(255) DEFAULT NULL,
  `manufacturer_part_number` varchar(255) DEFAULT NULL,
  `manufacturer_model_number` varchar(255) DEFAULT NULL,
  `contributors` text,
  `content_info` text,
  `content_rating` text,
  `release_date` timestamp NULL DEFAULT NULL,
  `reviews` int(11) DEFAULT NULL,
  `ratings` int(11) DEFAULT NULL,
  `internal_path` varchar(255) DEFAULT NULL,
  `price` int(11) DEFAULT NULL,
  `adult_product` tinyint(4) DEFAULT NULL,
  `height` varchar(255) DEFAULT NULL,
  `length` varchar(255) DEFAULT NULL,
  `width` varchar(255) DEFAULT NULL,
  `weight` varchar(255) DEFAULT NULL,
  `scraped` tinyint(4) NOT NULL DEFAULT '0',
  `scraped_timestamp` timestamp NULL DEFAULT NULL,
  `scrape_attempt_timestamp` timestamp NULL DEFAULT NULL,
  `processed` tinyint(4) NOT NULL DEFAULT '0',
  `processed_timestamp` timestamp NULL DEFAULT NULL,
  `modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `scrape_dump` longtext,
  PRIMARY KEY (`id`),
  UNIQUE KEY `id_UNIQUE` (`id`),
  UNIQUE KEY `url_UNIQUE` (`url`),
  UNIQUE KEY `internal_barcode_UNIQUE` (`internal_barcode`),
  KEY `bzic` (`bzic`),
  KEY `pzic` (`pzic`),
  KEY `internal_barcode` (`internal_barcode`),
  KEY `external_barcode` (`external_barcode`,`external_barcode_type`) /*!80000 INVISIBLE */,
  KEY `scrape_attempt` (`bzic`,`scraped`,`scrape_attempt_timestamp`)
) ENGINE=InnoDB AUTO_INCREMENT=121674 DEFAULT CHARSET=latin1;


第二个查询可能受益于已经包含第一个查询结果的缓存

此外,在第二个子查询中,您只需选择使用两列(id,external_barcode)在这两列中都在索引中。所有查询结果仅通过索引扫描获得,而在第一次查询中,要检索所有数据,查询必须扫描所有表行

为了避免第一次查询的时间过长,您应该在
external\u barcode
列中添加适当的索引

create index my_idx  on scraper_data (external_barcode, id)

您的查询不相等,如果有多行带有该条形码,则第二次查询将抛出错误:

错误代码:1242。子查询返回超过1行

这可能就是这里发生的情况:您实际上并没有得到一个结果,只是一个错误。由于MySQL可以在找到第二行时立即停止全表扫描,因此,如果这些行位于扫描的第一行中(例如在
id
s1和2中),则可以比正确的结果更快地得到此错误,包括“0.00s”

从执行计划中,您可以看到两者都执行完整的表扫描(在当前版本中,包括读取blob字段),因此执行速度应该类似地快(因为第二个解释计划中的第一个条目仅在几行中可以忽略)

因此,对于不会引发错误的条形码,您的两个查询以及已更正的第二个查询(您在中使用
,而不是
=

以及运行子查询

SELECT id FROM scraper_data WHERE external_barcode = '032429257284'
另外(如果您的假设是正确的,则必须比您的第二次查询更快)将有类似的(长)执行时间

如中所述,在
external_barcode
上建立索引将显著提高性能,因为您不需要进行完整的表格扫描,也不需要读取blob字段。实际上您有这样一个索引,但是您禁用了它(
不可见的
)。您可以使用

ALTER TABLE scraper_data ALTER INDEX `external_barcode` VISIBLE;

显示statemetns和CREATE Table scraper的示例_data@nbk更新的postMaybe您只需在第一个查询之后运行第二个查询。因此,它使用第一个查询的缓存结果?@IldarAkhmetov第一个查询需要很长时间,因此我构建了第二个查询作为优化。它们没有一起运行。这两个查询没有一起运行。第一个查询需要很长时间,所以我构建了第二个查询作为优化。文章显示,外部条形码也已经有了索引。这两个查询都在where子句中使用外部\u条形码,因此在比较两个查询的性能差异时,索引的存在应该没有什么区别。两个查询中的外部\u条形码列都被索引,并且这些查询不会一起运行。SELECT语句中捕获的内容应该不会影响WHERE子句中发生的内容。您有一个带有外部条形码id???的索引。。如果这是真的,子查询将被解析,只需访问索引,并且只访问与匹配的外部条形码相关的行。。。在第一个查询中。。您还需要有others列,为此,查询必须访问表数据。。请记住,查询优化器分析所有查询子句。。在开始和结束选择时启动。。并计算解决查询所需的所有列。。并在此基础上执行对索引(仅)和/或表的正确访问WHERE子句在两个查询中完全相同。只需选择*。另一个SELECT id。选择id的那个将用第二个查询包装,该查询显示SELECT*FROM id。执行双倍工作的那个将更快。这似乎反映了您从结果中选择的内容会影响WHERE子句查找结果的速度,但不会影响SELECT。。与子查询返回的id匹配的外部查询。。id可能是主键,并且具有索引。。子查询将外部_条形码用于具有索引的匹配。。第一个查询执行表的完整扫描,以获取所有列的值。。