- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的 Web 应用程序对 DBMS Mysql 5.7.23 进行了一些查询。
该表有大约 80 万条记录。这是具有实际索引的表的 DDL:
CREATE TABLE `contactlens`
(
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`createdBy` varchar(255) DEFAULT NULL,
`createdDate` datetime(6) NOT NULL,
`lastModifiedBy` varchar(255) DEFAULT NULL,
`lastModifiedDate` datetime(6) DEFAULT NULL,
`sid` varchar(36) NOT NULL,
`version` bigint(20) NOT NULL,
`brand` varchar(255) DEFAULT NULL,
`category` varchar(255) DEFAULT NULL,
`colorCode` varchar(255) DEFAULT NULL,
`colorDescription` varchar(255) DEFAULT NULL,
`description` longtext,
`imageUrl` varchar(255) DEFAULT NULL,
`lastPurchase` datetime(6) DEFAULT NULL,
`lastPurchasePrice` decimal(19,2) DEFAULT NULL,
`lastSell` datetime(6) DEFAULT NULL,
`lastSellPrice` decimal(19,2) DEFAULT NULL,
`line` varchar(255) DEFAULT NULL,
`manufacturer` varchar(255) DEFAULT NULL,
`manufacturerCode` varchar(255) DEFAULT NULL,
`name` varchar(255) NOT NULL,
`preset` bit(1) NOT NULL DEFAULT b'0',
`purchasePrice` decimal(19,2) DEFAULT NULL,
`salesPrice` decimal(19,2) DEFAULT NULL,
`sku` varchar(255) NOT NULL,
`stock` bit(1) NOT NULL DEFAULT b'1',
`thumbUrl` varchar(255) DEFAULT NULL,
`trial` bit(1) NOT NULL DEFAULT b'0',
`upc` varchar(255) DEFAULT NULL,
`additionMax` decimal(10,2) DEFAULT NULL,
`additionMin` decimal(10,2) DEFAULT NULL,
`axisMax` int(11) DEFAULT NULL,
`axisMin` int(11) DEFAULT NULL,
`baseCurveMax` decimal(10,2) DEFAULT NULL,
`baseCurveMin` decimal(10,2) DEFAULT NULL,
`cylinderMax` decimal(10,2) NOT NULL,
`cylinderMin` decimal(10,2) NOT NULL,
`design` varchar(30) NOT NULL,
`diameterMax` decimal(10,1) DEFAULT NULL,
`diameterMin` decimal(10,1) DEFAULT NULL,
`dominant` bit(1) DEFAULT NULL,
`duration` int(11) NOT NULL,
`family` varchar(30) DEFAULT NULL,
`material` varchar(255) DEFAULT NULL,
`pack` int(11) NOT NULL,
`source` varchar(30) NOT NULL,
`sphereMax` decimal(10,2) NOT NULL,
`sphereMin` decimal(10,2) NOT NULL,
`type` varchar(30) NOT NULL,
`taxRate_id` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `idx_sku` (`sku`),
UNIQUE KEY `UK_elol05sqtuwi88exc8cdmqul1` (`sid`),
UNIQUE KEY `idx_upc` (`upc`),
KEY `idx_design` (`design`),
KEY `FKq7sw02khmcn1nqil9pcxkgmfa` (`taxRate_id`),
KEY `idx_manufacturer_line_duration_sph_cyl_add` (`type`,`design`,`line`,`duration`,`sphereMin`,`sphereMax`,`cylinderMin`,`cylinderMax`,`axisMin`,`axisMax`,`additionMin`,`additionMax`,`manufacturer`),
KEY `idx_sorting` (`manufacturer`,`line`,`duration`,`sphereMin`,`cylinderMin`,`additionMin`),
CONSTRAINT `FKq7sw02khmcn1nqil9pcxkgmfa` FOREIGN KEY (`taxRate_id`) REFERENCES `taxrate` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2572246 DEFAULT CHARSET=utf8
Web 应用程序显示其中一些数据,并允许用户对每一列进行过滤(如 Google 电子表格文档中的过滤器)。
使用可以过滤这些列:
manufacturer | line | type | design | duration | pack | baseCurve (mix/max) | Sph (min/max) | Cyl (min/max) | Axis (min/max) | Addition (min/max)
所有查询都有一个默认的排序依据。最常见的查询是:
查询 1
SELECT *
FROM `ContactLens` contactlen0_
WHERE 1=1
ORDER BY contactlen0_.`manufacturer` ASC, contactlen0_.`line` ASC, contactlen0_.`duration` ASC , contactlen0_.`sphereMin` ASC, contactlen0_.`cylinderMin` ASC, contactlen0_.`additionMin` ASC
LIMIT 10
如您所见,idx_sorting
按预期使用。查询耗时大约 6 毫秒,这很好。
查询 2
这次我有过滤器和排序方式。
SELECT *
FROM `ContactLens` contactlen0_
WHERE 1=1
AND contactlen0_.`sphereMin`<=1.25
AND contactlen0_.`sphereMax`>=1.75
AND contactlen0_.`additionMin`<=2.25
AND contactlen0_.`additionMax`>=2.5
AND contactlen0_.`type`='MULTI_FOCAL'
ORDER BY contactlen0_.`manufacturer` ASC, contactlen0_.`line` ASC, contactlen0_.`duration` ASC , contactlen0_.`sphereMin` ASC, contactlen0_.`cylinderMin` ASC, contactlen0_.`additionMin` ASC
LIMIT 10
对此进行解释,您可以看到使用了 idx_sorting,而我预计它使用了 idx_manufacturer_line_duration_sph_cyl_add
索引。查询需要 4 秒:很多!我不明白:
使用了“错误的索引”
为什么即使使用 idx_manufacturer_line_duration_sph_cyl_add,考虑到行基数为 20,查询仍需要这么长时间
这是优化轨迹:
{
"steps": [
{
"join_preparation": {
"select#": 1,
"steps": [
{
"expanded_query": "/* select#1 */ select `contactlen0_`.`id` AS `id`,`contactlen0_`.`createdBy` AS `createdBy`,`contactlen0_`.`createdDate` AS `createdDate`,`contactlen0_`.`lastModifiedBy` AS `lastModifiedBy`,`contactlen0_`.`lastModifiedDate` AS `lastModifiedDate`,`contactlen0_`.`sid` AS `sid`,`contactlen0_`.`version` AS `version`,`contactlen0_`.`brand` AS `brand`,`contactlen0_`.`category` AS `category`,`contactlen0_`.`colorCode` AS `colorCode`,`contactlen0_`.`colorDescription` AS `colorDescription`,`contactlen0_`.`description` AS `description`,`contactlen0_`.`imageUrl` AS `imageUrl`,`contactlen0_`.`lastPurchase` AS `lastPurchase`,`contactlen0_`.`lastPurchasePrice` AS `lastPurchasePrice`,`contactlen0_`.`lastSell` AS `lastSell`,`contactlen0_`.`lastSellPrice` AS `lastSellPrice`,`contactlen0_`.`line` AS `line`,`contactlen0_`.`manufacturer` AS `manufacturer`,`contactlen0_`.`manufacturerCode` AS `manufacturerCode`,`contactlen0_`.`name` AS `name`,`contactlen0_`.`preset` AS `preset`,`contactlen0_`.`purchasePrice` AS `purchasePrice`,`contactlen0_`.`salesPrice` AS `salesPrice`,`contactlen0_`.`sku` AS `sku`,`contactlen0_`.`stock` AS `stock`,`contactlen0_`.`thumbUrl` AS `thumbUrl`,`contactlen0_`.`trial` AS `trial`,`contactlen0_`.`upc` AS `upc`,`contactlen0_`.`additionMax` AS `additionMax`,`contactlen0_`.`additionMin` AS `additionMin`,`contactlen0_`.`axisMax` AS `axisMax`,`contactlen0_`.`axisMin` AS `axisMin`,`contactlen0_`.`baseCurveMax` AS `baseCurveMax`,`contactlen0_`.`baseCurveMin` AS `baseCurveMin`,`contactlen0_`.`cylinderMax` AS `cylinderMax`,`contactlen0_`.`cylinderMin` AS `cylinderMin`,`contactlen0_`.`design` AS `design`,`contactlen0_`.`diameterMax` AS `diameterMax`,`contactlen0_`.`diameterMin` AS `diameterMin`,`contactlen0_`.`dominant` AS `dominant`,`contactlen0_`.`duration` AS `duration`,`contactlen0_`.`family` AS `family`,`contactlen0_`.`material` AS `material`,`contactlen0_`.`pack` AS `pack`,`contactlen0_`.`source` AS `source`,`contactlen0_`.`sphereMax` AS `sphereMax`,`contactlen0_`.`sphereMin` AS `sphereMin`,`contactlen0_`.`type` AS `type`,`contactlen0_`.`taxRate_id` AS `taxRate_id` from `contactlens` `contactlen0_` where ((1 = 1) and (`contactlen0_`.`sphereMin` <= 1.25) and (`contactlen0_`.`sphereMax` >= 1.75) and (`contactlen0_`.`additionMin` <= 2.25) and (`contactlen0_`.`additionMax` >= 2.5) and (`contactlen0_`.`type` = 'MULTI_FOCAL')) order by `contactlen0_`.`manufacturer`,`contactlen0_`.`line`,`contactlen0_`.`duration`,`contactlen0_`.`sphereMin`,`contactlen0_`.`cylinderMin`,`contactlen0_`.`additionMin` limit 10"
}
]
}
},
{
"join_optimization": {
"select#": 1,
"steps": [
{
"condition_processing": {
"condition": "WHERE",
"original_condition": "((1 = 1) and (`contactlen0_`.`sphereMin` <= 1.25) and (`contactlen0_`.`sphereMax` >= 1.75) and (`contactlen0_`.`additionMin` <= 2.25) and (`contactlen0_`.`additionMax` >= 2.5) and (`contactlen0_`.`type` = 'MULTI_FOCAL'))",
"steps": [
{
"transformation": "equality_propagation",
"resulting_condition": "((1 = 1) and (`contactlen0_`.`sphereMin` <= 1.25) and (`contactlen0_`.`sphereMax` >= 1.75) and (`contactlen0_`.`additionMin` <= 2.25) and (`contactlen0_`.`additionMax` >= 2.5) and (`contactlen0_`.`type` = 'MULTI_FOCAL'))"
},
{
"transformation": "constant_propagation",
"resulting_condition": "((1 = 1) and (`contactlen0_`.`sphereMin` <= 1.25) and (`contactlen0_`.`sphereMax` >= 1.75) and (`contactlen0_`.`additionMin` <= 2.25) and (`contactlen0_`.`additionMax` >= 2.5) and (`contactlen0_`.`type` = 'MULTI_FOCAL'))"
},
{
"transformation": "trivial_condition_removal",
"resulting_condition": "((`contactlen0_`.`sphereMin` <= 1.25) and (`contactlen0_`.`sphereMax` >= 1.75) and (`contactlen0_`.`additionMin` <= 2.25) and (`contactlen0_`.`additionMax` >= 2.5) and (`contactlen0_`.`type` = 'MULTI_FOCAL'))"
}
]
}
},
{
"substitute_generated_columns": {
}
},
{
"table_dependencies": [
{
"table": "`contactlens` `contactlen0_`",
"row_may_be_null": false,
"map_bit": 0,
"depends_on_map_bits": [
]
}
]
},
{
"ref_optimizer_key_uses": [
{
"table": "`contactlens` `contactlen0_`",
"field": "type",
"equals": "'MULTI_FOCAL'",
"null_rejecting": false
}
]
},
{
"rows_estimation": [
{
"table": "`contactlens` `contactlen0_`",
"range_analysis": {
"table_scan": {
"rows": 728004,
"cost": 171586
},
"potential_range_indexes": [
{
"index": "PRIMARY",
"usable": false,
"cause": "not_applicable"
},
{
"index": "idx_sku",
"usable": false,
"cause": "not_applicable"
},
{
"index": "UK_elol05sqtuwi88exc8cdmqul1",
"usable": false,
"cause": "not_applicable"
},
{
"index": "idx_upc",
"usable": false,
"cause": "not_applicable"
},
{
"index": "FKq7sw02khmcn1nqil9pcxkgmfa",
"usable": false,
"cause": "not_applicable"
},
{
"index": "idx_manufacturer_line_duration_sph_cyl_add",
"usable": true,
"key_parts": [
"type",
"design",
"line",
"duration",
"sphereMin",
"sphereMax",
"cylinderMin",
"cylinderMax",
"axisMin",
"axisMax",
"additionMin",
"additionMax",
"manufacturer",
"id"
]
},
{
"index": "idx_sorting",
"usable": false,
"cause": "not_applicable"
},
{
"index": "idx_design",
"usable": false,
"cause": "not_applicable"
}
],
"setup_range_conditions": [
],
"group_index_range": {
"chosen": false,
"cause": "not_group_by_or_distinct"
},
"analyzing_range_alternatives": {
"range_scan_alternatives": [
{
"index": "idx_manufacturer_line_duration_sph_cyl_add",
"ranges": [
"MULTI_FOCAL <= type <= MULTI_FOCAL"
],
"index_dives_for_eq_ranges": true,
"rowid_ordered": false,
"using_mrr": false,
"index_only": false,
"rows": 364002,
"cost": 436803,
"chosen": false,
"cause": "cost"
}
],
"analyzing_roworder_intersect": {
"usable": false,
"cause": "too_few_roworder_scans"
}
}
}
}
]
},
{
"considered_execution_plans": [
{
"plan_prefix": [
],
"table": "`contactlens` `contactlen0_`",
"best_access_path": {
"considered_access_paths": [
{
"access_type": "ref",
"index": "idx_manufacturer_line_duration_sph_cyl_add",
"rows": 364002,
"cost": 145601,
"chosen": true
},
{
"rows_to_scan": 728004,
"access_type": "scan",
"resulting_rows": 4492.1,
"cost": 171584,
"chosen": false
}
]
},
"condition_filtering_pct": 1.2341,
"rows_for_plan": 4492.1,
"cost_for_plan": 145601,
"chosen": true
}
]
},
{
"attaching_conditions_to_tables": {
"original_condition": "((`contactlen0_`.`sphereMin` <= 1.25) and (`contactlen0_`.`sphereMax` >= 1.75) and (`contactlen0_`.`additionMin` <= 2.25) and (`contactlen0_`.`additionMax` >= 2.5) and (`contactlen0_`.`type` = 'MULTI_FOCAL'))",
"attached_conditions_computation": [
],
"attached_conditions_summary": [
{
"table": "`contactlens` `contactlen0_`",
"attached": "((`contactlen0_`.`sphereMin` <= 1.25) and (`contactlen0_`.`sphereMax` >= 1.75) and (`contactlen0_`.`additionMin` <= 2.25) and (`contactlen0_`.`additionMax` >= 2.5))"
}
]
}
},
{
"clause_processing": {
"clause": "ORDER BY",
"original_clause": "`contactlen0_`.`manufacturer`,`contactlen0_`.`line`,`contactlen0_`.`duration`,`contactlen0_`.`sphereMin`,`contactlen0_`.`cylinderMin`,`contactlen0_`.`additionMin`",
"items": [
{
"item": "`contactlen0_`.`manufacturer`"
},
{
"item": "`contactlen0_`.`line`"
},
{
"item": "`contactlen0_`.`duration`"
},
{
"item": "`contactlen0_`.`sphereMin`"
},
{
"item": "`contactlen0_`.`cylinderMin`"
},
{
"item": "`contactlen0_`.`additionMin`"
}
],
"resulting_clause_is_simple": true,
"resulting_clause": "`contactlen0_`.`manufacturer`,`contactlen0_`.`line`,`contactlen0_`.`duration`,`contactlen0_`.`sphereMin`,`contactlen0_`.`cylinderMin`,`contactlen0_`.`additionMin`"
}
},
{
"added_back_ref_condition": "((`contactlen0_`.`type` <=> 'MULTI_FOCAL') and ((`contactlen0_`.`sphereMin` <= 1.25) and (`contactlen0_`.`sphereMax` >= 1.75) and (`contactlen0_`.`additionMin` <= 2.25) and (`contactlen0_`.`additionMax` >= 2.5)))"
},
{
"reconsidering_access_paths_for_index_ordering": {
"clause": "ORDER BY",
"index_order_summary": {
"table": "`contactlens` `contactlen0_`",
"index_provides_order": true,
"order_direction": "asc",
"index": "idx_sorting",
"plan_changed": true,
"access_type": "index"
}
}
},
{
"refine_plan": [
{
"table": "`contactlens` `contactlen0_`"
}
]
}
]
}
},
{
"join_execution": {
"select#": 1,
"steps": [
]
}
}
]
}
强制使用idx_manufacturer_line_duration_sph_cyl_add索引,解释查询:
SELECT *
FROM `ContactLens` contactlen0_
USE INDEX (idx_manufacturer_line_duration_sph_cyl_add)
WHERE 1=1
AND contactlen0_.`sphereMin`<=1.25
AND contactlen0_.`sphereMax`>=1.75
AND contactlen0_.`additionMin`<=2.25
AND contactlen0_.`additionMax`>=2.5
AND contactlen0_.`type`='MULTI_FOCAL'
ORDER BY contactlen0_.`manufacturer` ASC, contactlen0_.`line` ASC, contactlen0_.`duration` ASC , contactlen0_.`sphereMin` ASC, contactlen0_.`cylinderMin` ASC, contactlen0_.`additionMin` ASC
LIMIT 10
这是查询的解释:
所以使用了“正确”的索引;即使行基数为 403245(因此比以前大得多),查询也需要 400 毫秒。
我基于 this paper 创建了索引。
什么是我可以使用的最好的索引来涵盖在我的案例中可以生成的大多数查询?
为什么在查询 2 中“正确的”索引比“错误的”索引快得多,即使它适用于 40 万行?
我如何提示 mysql(不明确地这样做)使用正确的索引?
======== 与 MYSQL 8 和 RDS AURORA 的比较 ======
根据@oysteing 的建议,我在 Mysql 8(8.0.11 和 8.0.13)和 RDS Aurora 上测试了查询 2。这是我得到的结果
Mysql 8.0.11
优化器跟踪:https://codeshare.io/2BXVeK
Mysql 8.0.13
优化器跟踪:https://codeshare.io/5Ookyr
并尝试在列上使用直方图:
RDS 极光
最佳答案
在这里查看我的回答:https://stackoverflow.com/a/52033986/3481706
在你的例子中,查询优化器显然认为它可以从 idx_sorting 索引中读取几行 (20) 来找到满足 WHERE 条件的前 10 行。这似乎有点奇怪,因为 EXPLAIN 说它估计只有 0.62% 可以满足条件。 (也许这里的 LIMIT 优化有一个错误。如果我有优化器跟踪,我可能会告诉更多。)最终结果是,通过使用 idx_sorting,它将访问远远超过它找到之前估计的 20 行满足查询的 10 行。
您可以尝试升级到MySQL 8.0,看看这个问题是否已经解决。在 8.0 中,您还可以在用于改善过滤估计的列上创建直方图。
一般情况下,在创建复合索引时,应将等式条件下使用的列放在最前面。很难创建一个能很好地覆盖所有类型查询的索引,因为 MySQL 只能使用索引的前缀,除了最后一列外,所有列都具有相等条件。这在 MySQL 8.0 中有了新的 skip-scan access method 改进。 .此方法允许使用索引前缀中的一个间隙。
关于mysql取错索引,排序索引而不是过滤索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53982463/
我正在尝试对每个条目有多个值的关联数组进行排序。 例如 [0] => stdClass Object ( [type] => node [sid] => 158 [score] => 0.059600
我在 mysql 中有“日期”列以这种格式保存日期 2014 年 9 月 17 日(日-月-年) 我需要对它们进行升序排序,所以我使用了这个命令: SELECT * FROM table ORDER
我目前正在将 MySQL 存储过程重写为 MS SQL 存储过程,但遇到了问题。 在 MySQL 存储过程中,有一个游标,它根据最近的日期 (effdate) 选择一个值并将其放入变量 (thestt
我想要 gwt r.QuestionId- 排序。但是我得到未排序的 QuestionId 尽管我提到了 QuestionId ASC 的顺序。 SELECT r.QuestionId,
我有一个关于在 scandir 函数中排序的基本问题。到目前为止,我阅读了 POSIX readdir 的手册页,但没有找到有关订购保证的具体信息。 但是当我遍历大目录(无法更改,只读)时,我在多个系
基本上我必须从 SQL 数据库中构建项目列表,但是用户可以选择对 7 个过滤器的任意组合进行过滤,也可以选择要排序的列以及按方向排序。 正如您可以想象的那样,这会以大量不同的组合进行编码,并且数据集非
我有两张 table 。想象第一个是一个目录,包含很多文件(第二个表)。 第二个表(文件)包含修改日期。 现在,我想选择所有目录并按修改日期 ASC 对它们进行排序(因此,最新的修改最上面)。我不想显
我想先根据用户的状态然后根据用户名来排序我的 sql 请求。该状态由 user_type 列设置: 1=活跃,2=不活跃,3=创始人。 我会使用此请求来执行此操作,但它不起作用,因为我想在“活跃”成员
在 C++ 中,我必须实现一个“类似 Excel/Access”(引用)的查询生成器,以允许对数据集进行自定义排序。如果您在 Excel 中使用查询构建器或 SQL 中的“ORDER BY a, b,
我面临这样的挑战: 检索按字段 A 排序的文档 如果字段 B 存在/不为空 . 否则 按字段排序 C. 在 SQL 世界中,我会做两个查询并创建一个 UNION SELECT,但我不知道如何从 Mon
我想对源列表执行以下操作: map 列表 排序 折叠 排序 展开 列表 其中一些方法(例如map和toList)是可链接的,因为它们返回非空对象。但是,sort 方法返回 void,因为它对 List
我制作了一个用于分析 Windows 日志消息编号的脚本。 uniq -c 数字的输出很难预测,因为根据数字的大小会有不同的空白。此时,我手动删除了空白。 这是对消息进行排序和计数的命令: cat n
我有以下词典: mydict1 = {1: 11, 2: 4, 5: 1, 6: 1} mydict2 = {1: 1, 5: 1} 对于它们中的每一个,我想首先按值(降序)排序,然后按键(升序)排序
我刚刚开始使用泛型,目前在对多个字段进行排序时遇到问题。 案例: 我有一个 PeopleList 作为 TObjectList我希望能够通过一次选择一个排序字段,但尽可能保留以前的排序来制作类似 Ex
有没有办法在 sql 中组合 ORDER BY 和 IS NULL 以便我可以在列不为空时按列排序,但如果它为null,按另一列排序? 最佳答案 类似于: ORDER BY CASE WHEN
我有一个包含 2 列“id”和“name”的表。 id 是常规的自动增量索引,name 只是 varchar。 id name 1 john 2 mary 3 pop 4 mary 5 j
场景 网站页面有一个带有分页、过滤、排序功能的表格 View 。 表中的数据是从REST API服务器获取的,数据包含数百万条记录。 数据库 REST API 服务器 Web 服务器 浏览器 问
假设我有一本字典,其中的键(单词)和值(分数)如下: GOD 8 DONG 16 DOG 8 XI 21 我想创建一个字典键(单词)的 NSArray,首先按分数排序,然后按字
如何在 sphinx 上通过 sql 命令选择前 20 行按标题 WEIGHT 排序,接下来 20 行按标题 ASC 排序(总共 40 个结果),但不要给出重复的标题输出。 我尝试了这个 sql 命令
我有一个奇怪的问题,当从 SQLite 数据库中选择信息并根据日期排序时,返回的结果无效。 我的SQL语句是这样的: Select pk from usersDates order by dateti
我是一名优秀的程序员,十分优秀!