如何在索引列的查询中使用限制而不扫描所有行?

2024-01-02

这是我的桌子:

在我的桌子上

  • Clustering_key(主键和自增量)
  • ID(索引栏)
  • Data(文本数据类型列)
  • Position(索引栏)维持顺序Data

我的表有 90,000 行,内容相同ID等于 5。我想要前 3 行ID等于 5 我的查询是这样的

Select * from mytable where ID=5 Limit 3;

ID列是索引列所以我认为mysql只扫描前3行但mysql扫描大约42000行。

这里解释一下查询:

任何避免所有行扫描的可能性。

请给我一些解决方案

提前致谢


我模拟了这个场景。

  • 使用创建表



   CREATE TABLE mytable (
        Clustering_key INT NOT NULL AUTO_INCREMENT,
        ID INT NOT NULL,
        Data text NOT NULL,
        Position INT NOT NULL,
        PRIMARY KEY (Clustering_key),
        KEY(ID),
        KEY(Position)
    )

  
  • 插入的数据与



    INSERT INTO mytable (ID,Data,Position) VALUES (5,CONCAT("Data-",5), 7);
    INSERT INTO mytable (ID,Data,Position) VALUES (5,CONCAT("Data-",5), 26);
    INSERT INTO mytable (ID,Data,Position) VALUES (5,CONCAT("Data-",51), 27);
    INSERT INTO mytable (ID,Data,Position) VALUES (5,CONCAT("Data-",56), 28);
    INSERT INTO mytable (ID,Data,Position) VALUES (5,CONCAT("Data-",57), 31);

  
  • Explain



    mysql> explain Select * from mytable where ID=5 Limit 3
    +----+-------------+---------+------------+------+---------------+------+---------+-------+------+----------+-------+
    | id | select_type | table   | partitions | type | possible_keys | key  | key_len | ref   | rows | filtered | Extra |
    +----+-------------+---------+------------+------+---------------+------+---------+-------+------+----------+-------+
    |  1 | SIMPLE      | mytable | NULL       | ref  | ID            | ID   | 4       | const |    5 |   100.00 | NULL  |
    +----+-------------+---------+------------+------+---------------+------+---------+-------+------+----------+-------+
    1 row in set, 1 warning (0.00 sec)

  

是的explain显示检查的行是 5,而不是 3。 但似乎这只是一个误导性的信息。 可以通过以下步骤为所有查询启用慢速日志(设置 long_query_time=0)来验证运行时 rows_examined 的确切数量。

注意:您必须仅在您自己的测试数据库中设置 long_query_time=0。并且测试后必须将参数重置回之前的值。




     - set GLOBAL slow_query_log=1;
     - set global long_query_time=0;
     - set session long_query_time=0;
     mysql> show variables like '%slow%';
    +---------------------------+-------------------------------------------------+
    | Variable_name             | Value                                           |
    +---------------------------+-------------------------------------------------+
    | log_slow_admin_statements | OFF                                             |
    | log_slow_slave_statements | OFF                                             |
    | slow_launch_time          | 2                                               |
    | slow_query_log            | ON                                              |
    | slow_query_log_file       | /usr/local/mysql/data/slow.log                  |
    +---------------------------+-------------------------------------------------+
    5 rows in set (0.10 sec)
    mysql> select @@long_query_time;
    +-------------------+
    | @@long_query_time |
    +-------------------+
    |          0.000000 |
    +-------------------+
      
And then in the terminal, executing the query
<pre>
mysql> Select * from mytable where ID=5 Limit 3;
+----------------+----+---------+----------+
| Clustering_key | ID | Data    | Position |
+----------------+----+---------+----------+
|              5 |  5 | Data-5  |        7 |
|          26293 |  5 | Data-5  |       26 |
|          26294 |  5 | Data-51 |       27 |
+----------------+----+---------+----------+
3 rows in set (0.00 sec)

mysql> Select * from mytable where ID=5 Limit 1;

通过检查来检查慢速日志slow_query_log_file上面印有/usr/local/mysql/data/slow.log

您可以通过以下方式了解信息。




    # Time: 2019-04-26T01:48:19.890846Z
    # User@Host: root[root] @ localhost []  Id:  5124
    # Query_time: 0.000575  Lock_time: 0.000146 Rows_sent: 3  Rows_examined: 3 
    SET timestamp=1556243299;
    Select * from mytable where ID=5 Limit 3;
    # Time: 2019-04-26T01:48:34.672888Z
    # User@Host: root[root] @ localhost []  Id:  5124
    # Query_time: 0.000182  Lock_time: 0.000074 Rows_sent: 1  Rows_examined: 1 
    SET timestamp=1556243314;
    Select * from mytable where ID=5 Limit 1;

  

运行时Rows_exmained值等于limit范围。 测试在MySQL 5.7.18上完成。

----------------------------------另一种验证方式------------------------ ----------------------





    mysql> show status like '%Innodb_rows_read%';
    +------------------+-------+
    | Variable_name    | Value |
    +------------------+-------+
    | Innodb_rows_read | 13    |
    +------------------+-------+
    1 row in set (0.00 sec)

    mysql> Select * from mytable where ID=5 Limit 1;
    +----------------+----+--------+----------+
    | Clustering_key | ID | Data   | Position |
    +----------------+----+--------+----------+
    |              5 |  5 | Data-5 |        7 |
    +----------------+----+--------+----------+
    1 row in set (0.00 sec)

    mysql> show status like '%Innodb_rows_read%';
    +------------------+-------+
    | Variable_name    | Value |
    +------------------+-------+
    | Innodb_rows_read | 14    |
    +------------------+-------+
    1 row in set (0.00 sec)

  

您可以看到Innodb_rows_read只需将限制 1 增加 1 即可。 如果执行全表扫描查询,您可以看到该值将增加表的计数。




    mysql> select count(*) from mytable;
    +----------+
    | count(*) |
    +----------+
    |   126296 |
    +----------+
    1 row in set (0.05 sec)

    mysql> show status like '%Innodb_rows_read%';
    +------------------+--------+
    | Variable_name    | Value  |
    +------------------+--------+
    | Innodb_rows_read | 505204 |
    +------------------+--------+
    1 row in set (0.00 sec)

    mysql> Select * from mytable where Data="Data-5";
    +----------------+----+--------+----------+
    | Clustering_key | ID | Data   | Position |
    +----------------+----+--------+----------+
    |              5 |  5 | Data-5 |        7 |
    |          26293 |  5 | Data-5 |       26 |
    |          26301 |  5 | Data-5 |        7 |
    +----------------+----+--------+----------+
    3 rows in set (0.09 sec)

    mysql> show status like '%Innodb_rows_read%';
    +------------------+--------+
    | Variable_name    | Value  |
    +------------------+--------+
    | Innodb_rows_read | 631500 |
    +------------------+--------+
    1 row in set (0.00 sec)

  

两种方式都证实了explainfor limit 似乎提供了有关所检查行的误导性信息。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在索引列的查询中使用限制而不扫描所有行? 的相关文章

  • 如何使用php在mysql中显示字幕中的多条新闻

    我在从 mysql 检索数据以在字幕中显示时遇到问题 当我访问网页时 它仅在字幕中显示数据库中的一项数据 我的问题是如何检索所有存储的数据 谢谢 下面是代码部分 select SELECT newsid headlines from new
  • 使用 PHP 连接到 Amazon RDS

    我正在尝试将 RDS 实例与 PHP 连接文件连接 这是我的文件中的内容 define DB SERVER localhost define DB USERNAME User Name define DB PASSWORD Password
  • Django migrate:不创建表

    经过一些错误后 我删除了数据库 删除了所有迁移文件 我留下了init py 现在 当我跑步时 python migrate py makemigrations It creates migrations correctly python m
  • mysql 更新或插入多条记录(如果表中尚不存在)

    mysql 数据库中有一个名为 inventory item 的表 id product id 和 quantity 是表的列 id 是主键 在插入记录时自动生成 当用户提交要向表中插入多条记录的表单时 可以在 foreach 循环中收集所
  • 同一张表上的多对多

    有趣的是我从来没有遇到过这个 我从来没有想过一个人可以在一张桌子上建立 多对多 关系 直到我开始开发一种用户可以互相 加好友 的系统 社交网络 标准查找表 至少以我习惯使用的方式 在这里不合适 让我们保持简单 用户表有 id 和 name
  • 具有数百万行的日志表。怎么办?

    我有一个包含数百万行的日志表 我正在考虑将数据分成多个表 即 LoginHistory ExceptionHistory PaymentProcessingHistory 等 在采用包含许多行 而不是列 的大型表并创建多个表时使用的术语是什
  • Java中对象的序列化需要什么? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 谁能告诉我Java中对象序列化的需求是什么 并给我一个示例场景来解释需求 我已经了解什么是序列化 我只是想了解何时使用它以及如何使用它
  • 具有 TINYTEXT 列的 CREATE TABLE 语句中出现语法错误 1064?

    这是我到目前为止的 MySQL 代码 CREATE DATABASE bankbase USE bankbase CREATE TABLE clienttable ClientID SMALLINT 15 NOT NULL DEFAULT
  • 获取ADO.NET中的参数前缀

    我想使用列名作为参数基于列列表生成多个 SQL 语句 Edit C var columns new string COL1 COL2 var tableName TABLE 1 var prefix TODO get this from t
  • WAMP/MySQL 错误语言不正确

    我已经多次重新安装WAMP 搜索了数百页 但仍未解决此问题 我查看了 phpmyadmin 配置文件 设置 cfg Lang en utf 8 卸载了多次 如上所述 似乎没有运气 任何帮助 将不胜感激 要更改 MySQL 在报告时使用的语言
  • ERROR 188 (HY000): FTS 查询超出结果缓存限制 mysql

    我的表的文本列上有全文索引 约有 1100 万行 表结构 CREATE TABLE review id int 11 NOT NULL AUTO INCREMENT comments text COLLATE utf8mb4 unicode
  • MYSQL嵌套查询运行速度很慢?

    以下查询不断超时 是否有开销更少的方法来实现相同的功能 UPDATE Invoices SET ispaid 0 WHERE Invoice number IN SELECT invoice number FROM payment allo
  • 如何将 PHP 会话数据保存到数据库而不是文件系统中?

    我有两个网站 一个是 TLS 一个不是 两个都适用于同一个客户端 但我需要这些网站彼此 并且仅彼此 共享通用数据users orders accounts etc 这通常可以通过以下方式完成 SESSION数据 但我显然这些不能跨其他站点工
  • MySQL 偏移无限行

    我想构造一个查询 显示表中的所有结果 但从表的开头偏移 5 据我所知 MySQLLIMIT需要一个限制和一个偏移量 有什么办法可以做到这一点吗 来自MySQL LIMIT 手册 http dev mysql com doc refman 5
  • 从 MySQL 列创建 PHP 数组

    mysql fetch array会给我一个获取行的数组 从一列中所有行的值生成数组的最佳方法是什么 您可以循环遍历数组并创建一个新数组 如下所示 column array while row mysql fetch array info
  • 私人消息数据库设计

    我正在创建一个简单的私人消息系统 但我不确定哪种数据库设计更好 第一个设计是一个消息表 以及一个消息评论表 Message id recipientId senderId title body created at MessageComme
  • 无法在 MySQL 中运行查询语法错误意外

    我正在运行工作台 5 2 47 我写了一个很长的程序 用于基本数据检查 如果数据库中不存在记录 则将插入该记录 该过程保存时没有任何问题 但当我尝试运行它时 MySQL 5 5 抛出错误 它很长 里面有很多公司敏感数据 或者我会把它发布在这
  • 'SQLSTATE[HY093]:参数数量无效:绑定变量的数量与令牌数量不匹配'[关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 我收到 SQLSTATE HY093 的错误 参数编号无效 绑定变量的数量与标记的数量不匹配 if isset POST cada
  • ECHO MYSQL 结果显示空白页 [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我知道这一定很简单 但我做不到 我需
  • 如何在 MySQL 查询编辑器中对列重新排序?

    我想移动专栏OtherSupport below Amount2 是否有捷径可寻 ALTER TABLE myTable MODIFY OtherSupport VARCHAR 50 AFTER Amount2

随机推荐

  • Pandas 数据透视表的逆

    我有一个数据框 例如 df p 已经转换为数据透视表 import pandas as pd df pd DataFrame start year 2000 2001 2002 end year 2010 2011 2012 price 1
  • Android 测试给出 IllegalStateException: 未注册仪器

    我按照谷歌教程编写了我的第一个 Android 测试 当然我得到了错误 java lang IllegalStateException No instrumentation registered Must run under a regis
  • 向 python 生成器添加元素

    是否可以将元素附加到 python 生成器 我目前正在尝试从一组杂乱的文件夹中获取所有图像并将它们写入一个新目录 为了获取文件 我使用 os walk 它返回单个目录中的图像文件列表 虽然我可以用这个列表创建一个生成器 但我不知道如何将所有
  • 哪种 NoSQL 数据库最适合仅附加审计日志记录用例?

    我的用例是资源的审核日志记录 为了进行讨论 考虑一个非常简单的模式 资源名称 访问时间戳和访问用户名 有了所有 NoSQL 选项 我想知道哪种解决方案最适合我的用例 资源名称保存在图形数据库 Neo4j 中 虽然我们可以将顶点和边添加到连接
  • 如何获取所有正在运行的活动android?

    我想知道有没有办法获得所有跑步活动的列表 据我了解 一次只会运行一个活动 该活动将是屏幕上的活动活动 其他活动将处于暂停或停止状态 如果有
  • Rails Mailer:将电子邮件发送到本地文件

    有什么方法可以将 Rails 3 中的电子邮件发送到本地文件等 而不是使用 SMTP 服务器吗 我想在不使用任何类型的 SMTP 的情况下测试电子邮件的内容 最好仅在 DEV 环境中测试 最好的是本地 SMTP 或允许我检查电子邮件 检查电
  • 如何使用 Passport.js 访问 OAuth 的状态参数?

    我正在使用 Passport js 进行身份验证 并且每个Google 的 OAuth2 文档 https developers google com accounts docs OAuth2Login formingtheurl 我传递一
  • Python:使用 pyOpenSSL.crypto 读取 pkcs12 证书

    我有西班牙权威机构 FNMT 颁发的有效证书 我想用它来了解更多信息 该文件的扩展名是 p12 我想阅读其中的信息 名字和姓氏 并检查证书是否有效 可以用 pyOpenSSL 做到这一点吗 我想我必须使用 OpenSSL 中的加密模块 有任
  • 如何在 StringBuilder 上检查 null?

    我想在我的代码中专门检查 null 或空 空和空是否相同StringBuilder在Java中 例如 StringBuilder state new StringBuilder StringBuilder err new StringBui
  • 如何使用反射获得泛型类型的正确文本定义?

    我正在研究代码生成 并遇到了泛型的障碍 这是导致我出现问题的 简化 版本 Dictionary
  • 在网络浏览器中打开 R Shiny 应用程序时,传单多边形会失去颜色

    我正在使用 R 中的传单构建地图 将其部署为 Shiny 应用程序 Shiny 应用程序在 RStudio 中运行良好 但是当我在网络浏览器中打开它时 多边形失去了颜色 其他一切都很好 底图在那里 多边形都在那里 您可以将鼠标悬停在多边形上
  • Ipython笔记本缓存问题

    在 ipython 笔记本中 我调用从我自己的模块导入的函数并运行一些代码 我注意到 如果我更改函数中的代码 在笔记本之外 并执行笔记本 则旧版本的函数将运行 当我记得时 ipython笔记本或firefox似乎正在缓存我可以用ctrl F
  • Python Byte 不打印二进制

    当我在 Python 中打印这样的程序时 x b francis 输出是b francis 如果字节在0 s and 1为什么它不打印出来 你似乎从根本上感到困惑 以一种非常常见的方式 数据本身是一个不同的概念表示 即当您尝试时所看到的pr
  • 页面滚动结束时的 jQuery 回调

    我有一个 div 标签 在 css 中设置为 overflow scroll 我有一个回调 应该在使用它找到的元素的滚动末尾调用 details scroll function if this height this get 0 scrol
  • 未找到 Android 方面,使用 Android Studio 0.2 进行编译时出现问题

    因此 遵循这篇 SO 帖子的建议 抱歉 我会在那里发表评论 希望我没有足够的声誉 Gradle 失败 无法确定要执行哪些任务 https stackoverflow com questions 17614477 gradle failure
  • vc++编译错误RC:致命错误RC1107:无效用法;使用RC /?为了

    我在构建 vc 项目时遇到以下错误 使用 Visual Studio 2010 RC 致命错误 RC1107 无效使用 使用RC 为了 我知道构建资源时存在一些问题 但如何获得确切的问题区域 Thanks 解决方案 在最后一个包含路径中添加
  • 简单的旋转悬停效果不起作用

    我正在尝试创建一个简单的效果 以便当我将鼠标悬停在最内圈时 两个外环旋转以创建很酷的效果 我认为这将是一项简单的任务 但我似乎无法弄清楚我做错了什么 当我将鼠标悬停在内圈上时 所有变化都是两个内圈向屏幕右下角移动 根本不旋转 我在这里缺少什
  • yii2 作曲家更新错误:版本字符串“2.*”无效

    我正在使用作曲家更新Yii2项目 但它正在退出但有异常 我已经将composer更新到最新版本 c6cc6dd6070871f4b198ed39f76dd8047c116b02 但它仍然不起作用 Importing tag v2 0 2 2
  • 何时在 C++ 中使用指针

    我刚刚开始学习C 中的指针 我不太确定何时使用指针 何时使用实际对象 例如 在我的一项作业中 我们必须构造一个 gPolyline 类 其中每个点都由一个 gVector 定义 现在 我的 gPolyline 类变量如下所示 private
  • 如何在索引列的查询中使用限制而不扫描所有行?

    这是我的桌子 在我的桌子上 Clustering key 主键和自增量 ID 索引栏 Data 文本数据类型列 Position 索引栏 维持顺序Data 我的表有 90 000 行 内容相同ID等于 5 我想要前 3 行ID等于 5 我的