MySQL 和嵌套集:慢 JOIN(不使用索引)

2023-11-21

我有两张桌子:

地区:

CREATE TABLE `localities` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(100) NOT NULL,
  `type` varchar(30) NOT NULL,
  `parent_id` int(11) DEFAULT NULL,
  `lft` int(11) DEFAULT NULL,
  `rgt` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `index_localities_on_parent_id_and_type` (`parent_id`,`type`),
  KEY `index_localities_on_name` (`name`),
  KEY `index_localities_on_lft_and_rgt` (`lft`,`rgt`)
) ENGINE=InnoDB;

定位:

CREATE TABLE `locatings` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `localizable_id` int(11) DEFAULT NULL,
  `localizable_type` varchar(255) DEFAULT NULL,
  `locality_id` int(11) NOT NULL,
  `category` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `index_locatings_on_locality_id` (`locality_id`),
  KEY `localizable_and_category_index` (`localizable_type`,`localizable_id`,`category`),
  KEY `index_locatings_on_category` (`category`)
) ENGINE=InnoDB;

localities 表作为嵌套集实现。

现在,当用户属于某个地点(通过某些定位)时,他也属于其所有祖先(更高级别的地点)。我需要一个查询,将所有用户所属的所有位置选择到视图中。

这是我的尝试:

select distinct lca.*, lt.localizable_type, lt.localizable_id 
from locatings lt
join localities lc on lc.id = lt.locality_id
left join localities lca on (lca.lft <= lc.lft and lca.rgt >= lc.rgt)

这里的问题是执行需要太多时间。

我咨询了解释:

+----+-------------+-------+--------+---------------------------------+---------+---------+----------------------------------+-------+----------+-----------------+
| id | select_type | table | type   | possible_keys                   | key     | key_len | ref                              | rows  | filtered | Extra           |
+----+-------------+-------+--------+---------------------------------+---------+---------+----------------------------------+-------+----------+-----------------+
|  1 | SIMPLE      | lt    | ALL    | index_locatings_on_locality_id  | NULL    | NULL    | NULL                             |  4926 |   100.00 | Using temporary |
|  1 | SIMPLE      | lc    | eq_ref | PRIMARY                         | PRIMARY | 4       | bzzik_development.lt.locality_id |     1 |   100.00 |                 |
|  1 | SIMPLE      | lca   | ALL    | index_localities_on_lft_and_rgt | NULL    | NULL    | NULL                             | 11439 |   100.00 |                 |
+----+-------------+-------+--------+---------------------------------+---------+---------+----------------------------------+-------+----------+-----------------+
3 rows in set, 1 warning (0.00 sec)

最后一个连接显然没有像我期望的那样使用 lft, rgt 索引。我很绝望。

更新: 按照 @cairnz 建议添加条件后,查询仍然需要太多时间来处理。

更新 2:列名而不是星号

更新的查询:

SELECT DISTINCT lca.id, lt.`localizable_id`, lt.`localizable_type` 
FROM locatings lt FORCE INDEX(index_locatings_on_category)
JOIN localities lc
    ON lc.id = lt.locality_id
INNER JOIN localities lca
    ON lca.lft <= lc.lft AND lca.rgt >= lc.rgt
WHERE lt.`category` != "Unknown";

更新说明:

+----+-------------+-------+--------+-----------------------------------------+-----------------------------+---------+---------------------------------+-------+----------+-------------------------------------------------+
| id | select_type | table | type   | possible_keys                           | key                         | key_len | ref                             | rows  | filtered | Extra                                           |
+----+-------------+-------+--------+-----------------------------------------+-----------------------------+---------+---------------------------------+-------+----------+-------------------------------------------------+
|  1 | SIMPLE      | lt    | range  | index_locatings_on_category             | index_locatings_on_category | 153     | NULL                            |  2545 |   100.00 | Using where; Using temporary                    |
|  1 | SIMPLE      | lc    | eq_ref | PRIMARY,index_localities_on_lft_and_rgt | PRIMARY                     | 4       | bzzik_production.lt.locality_id |     1 |   100.00 |                                                 |
|  1 | SIMPLE      | lca   | ALL    | index_localities_on_lft_and_rgt         | NULL                        | NULL    | NULL                            | 11570 |   100.00 | Range checked for each record (index map: 0x10) |
+----+-------------+-------+--------+-----------------------------------------+-----------------------------+---------+---------------------------------+-------+----------+-------------------------------------------------+

任何帮助表示赞赏。


啊,我刚刚想到的。

由于您要求表中的所有内容,因此 mysql 决定使用全表扫描,因为它认为这样更有效。

为了获得一些关键用法,请添加一些过滤器以限制查找所有表中的每一行。

更新答案:

您的第二个查询没有意义。您将左连接到 lca,但其中有一个过滤器,这会自行否定左连接。此外,您还要在查询的最后一步中查找数据,这意味着您必须查看所有 lt、lc 和 lca 才能找到数据。此外,您在位置上没有最左侧列“类型”的索引,因此您仍然需要全表扫描来查找数据。

如果您有一些示例数据和您想要实现的目标的示例,那么可能会更容易提供帮助。

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

MySQL 和嵌套集:慢 JOIN(不使用索引) 的相关文章

  • 为什么 sql 字段名称中不应该包含逗号?

    人们一直告诉我列名中不应包含空格 我只是想知道 这是为什么 这是我为学校创建的一些数据库表遇到的问题 字段名称包括 Preble 和 Darke 相反 它们需要是 普雷布尔县 俄亥俄州 和 达克县 俄亥俄州 如果它们是行名称 我只需创建一个
  • 混合语言源目录布局

    我们正在运行一个使用多种不同语言的大型项目 Java Python PHP SQL 和 Perl 到目前为止 人们一直在自己的私有存储库中工作 但现在我们希望将整个项目合并到一个存储库中 现在的问题是 目录结构应该是什么样的 我们应该为每种
  • 频繁插入已排序的集合

    我已经对集合 列表 进行了排序 并且我需要始终保持其排序 我目前在我的集合上使用 List BinarySearch 然后在正确的位置插入元素 我也尝试过在每次插入后对列表进行排序 但性能不可接受 有没有一种解决方案可以提供更好的性能 也许
  • Oracle:如何查找模式中上次更新(任何表)的时间戳?

    有一个Oracle数据库模式 数据很小 但仍然有10 15个表左右 它包含一种配置 路由表 有一个应用程序必须不时轮询此架构 不得使用通知 如果架构中没有数据更新 应用程序应使用其当前的内存版本 如果任何表有任何更新 应用程序应将所有表重新
  • 在 plsql 中立即执行

    如何从这段代码中得到结果 EXECUTE IMMEDIATE SELECT FROM table name through for loop 通常的方法看起来像这样 for items in select from this table l
  • WooCommerce:在数据库中查找产品

    我正在使用 WooCommerce 创建一个网站 我想根据用户在主页搜索表单中输入的邮政编码来限制用户可用的产品 为了能够实现这一目标 我必须在 phpMyAdmin 的数据库中指定每个产品的条件 但我似乎找不到它 有谁知道 phpmyAd
  • 返回行位置 - Postgres

    我返回一个带有位置的表 select from select row number over as position from organization result where data1 Hello 返回这个 这是正确的 data1 H
  • ER_ACCESS_DENIED_ERROR:用户 ''@'localhost' 的访问被拒绝(使用密码:NO)

    我有这个问题 我已经研究过但无法解决它 我想它与数据库权限有关 但我无法修复它 if error throw error Error ER ACCESS DENIED ERROR Access denied for user localho
  • 使用 PHP 代码和 HTML 表单将 Excel (.csv) 导入 MySQL

    我知道还有其他类似的帖子 但每个人都建议直接在 PHPMyAdmin 中将其导入 MySQL 这工作完美 但我需要通过 HTML 表单导入 PHP 到 MySQL 我想要一个收集文件的 HTML 表单 然后将该文件传递给 PHP 脚本 我想
  • 使用 EXPLAIN 进行 MYSQL 存储过程调用

    如何分析和使用 EXPLAIN 来调用我的存储过程 我需要优化查询时间 但是似乎没有地方可以执行 EXPLAIN 调用 proc name 你可以试试 set profiling 1 call proc name show profiles
  • MySql 查询在选择中将 NULL 替换为空字符串

    如何用空字符串替换 select 中的 NULL 值 输出 NULL 值看起来不太专业 这是非常不寻常的 根据我的语法 我希望它能够工作 我希望能得到一个解释 为什么没有 select CASE prereq WHEN prereq IS
  • 如何使用 PHP 从 MySQL 查询中按升序对值进行排序?

    我使用以下 PHP 脚本从 MySQL 表中获取和更改数据 并将结果打印在 HTML 表中 我希望按升序对数据进行排序 utilization percentage变量 它是由创建的 total client time total avai
  • 获取查询的行号

    我有一个查询将返回一行 当表排序时 有什么方法可以找到我正在查询的行的行索引吗 我试过了rowid但当我期待第 7 行时却得到了 582 Eg CategoryID Name I9GDS720K4 CatA LPQTOR25XR CatB
  • 具有 LINQ 支持的最完整的 ORM?

    我正在寻找一个提供完整或接近完整的 LINQ 支持的 ORM LINQ 到 SQL 支持 LINQ 内部的所有内容 Contains Math Log 等 在不创建新数据上下文的情况下无法预先加载关系属性 ADO NET 实体框架 糟糕的
  • 在nhibernate中设置聚集索引

    我试图在 nhibernate 中定义一个不是 id 的属性作为聚集索引 但我发现没有办法做到这一点 谁能给我指点一下这是如何完成的 或者它是当前在 nhibernate 中不可用的东西 提前致谢 您可以使用
  • 为什么在 this 方法中添加 If 语句会大大降低速度?

    我在中遇到过这个回答另一个问题 https stackoverflow com questions 12233594 faster way to apply alpha to a jpeg in an android app 我试图诊断哪些
  • Java中精确的时间测量

    Java 提供了两种获取当前时间的方法 System nanoTime and System currentTimeMillis 第一个给出的结果以纳秒为单位 但实际精度比这要差得多 许多微秒 JVM 是否已经为每台特定机器提供了最佳的价值
  • ejabberd 16.06 + mysql 5.5.50,消息历史记录不保存

    我使用ejabberd 16 06 mysql 5 5 50 消息历史记录没有保存 我的 ejabberd yml MySQL server odbc type mysql odbc server freldo odbc port 3306
  • php 崩溃后 mysql 表被锁定

    我有一个 MySQL DB 和一个 innoDB 表 我有一个 php 页面 用于连接 锁定表 进行一些更新 然后解锁表 PHP 页面通过 wamp 与 apache 一起提供 php页面将文件上传到数据库 我决定通过上传一个大小大于分配给
  • 如何打印Oracle中过程的定义?

    oracle中有没有办法查看过程的结构是什么 我正在尝试记录并运行程序 并希望将实际的程序结构存储在我的日志中 您可以查询ALL SOURCE table SELECT text FROM all source WHERE owner lt

随机推荐

  • 从 gulp 中使用 browserify 时如何向浏览器公开“require”?

    当我有一个如下所示的文件 x js 时 x js module exports function n return n 111 我从命令行运行 browserify 如下所示 browserify r x js gt bundle js 我
  • WinForms 应用程序的常见漏洞

    我不确定这是否是主题 但它是如此特定于 NET WinForms 因此我相信它在这里比在 Security stackexchange 站点更有意义 此外 它与安全编码 我认为这与我在网站上看到的常见网站漏洞的任何问题一样切题 多年来 我们
  • UINavigationBar 在 AppDelegate.swift 中设置自定义阴影

    我想在整个应用程序的 UINavigationBar 底部设置一些阴影 这是我尝试过但不起作用的方法 func application application UIApplication didFinishLaunchingWithOpti
  • docker autobuild 与 git private 子模块

    我在 GitHub 上有两个私有存储库 名为dashboard and ui 我定义了ui作为 git 子模块dashboard 我将 docker 配置为自动构建dashboard关于特定分支上的每个更改 我读过这个文档https doc
  • 会话欺骗 (PHP)

    我正在用 PHP 编写一个包含布尔值的网站 SESSION logged in 这被设置为true当数据库中存在用户名和密码匹配时 我对会话相当陌生 只是想知道未注册 或者注册 用户是否可以通过将此布尔值设置为来绕过登录过程true 就像
  • 角度 $http POST 到 target="_blank"

    我需要做一个POST从 Angular 到 URL makeFile php它将根据其中提供的信息创建一个包含数据库查询内容的文件POST data PHP 强制浏览器打开一个保存对话框 而不仅仅是显示以下两行响应 header Conte
  • 确定在 Tkinter 中按下了哪个按钮?

    我在学习 Python 的同时制作了一个简单的小实用程序 它动态生成按钮列表 for method in methods button Button self methodFrame text method command self pop
  • PHP scandir() 和 htmlentities():字符集和/或特殊字符的问题

    我在用jquery文件树显示服务器上的目录列表以及目录中文件的下载链接 最近我遇到了包含特殊字符的文件的问题 test pdf 工作正常 t st pdf 不起作用 注意文件名中的 重音符号 在调试 jqueryFileTree 的 php
  • Python 中的字符串混淆

    我有一个必须传递给方法的密码字符串 一切正常 但我觉得以明文形式存储密码不太舒服 有没有办法混淆字符串或真正加密它 我知道混淆可以进行逆向工程 但我认为我至少应该尝试稍微掩盖密码 至少它对于索引程序或快速浏览我的代码的杂散眼来说是不可见的
  • 如何在android项目api 3(android 1.5)中使用Base64(自api 8(2.2)起包含在android中)?

    我需要在我的应用程序上使用 Base64 import android util Base64 但是 Base64 包含在 android 2 2 中 api lvl 8 然后 当我进行导入时 我收到此错误 Base64 无法解析 并且不让
  • 每个VST SDK似乎都是针对C++的,那么C#呢?

    我想开始制作 VSTi 更具体地说 midi 那些不产生任何声音而只是将 midi 数据输出到其他 vst 插头 琶音器 和弦工具等 的 现在我刚刚买了 C 书籍 认为这将是一门不错的语言 不仅仅是 vst 编程 但每个人都一直说 C 是正
  • 如何以编程方式卸载flutter中的应用程序?

    我正在 flutter 中构建一个启动器应用程序 但我无法添加卸载功能 请帮我 添加权限在manifest file
  • 清理 SQL 数据

    谷歌出现了各种关于清理网络访问查询的讨论 但我没有找到任何解决我所关心的问题的内容 在 C 程序中清理用户输入数据 这必须通过可逆转变来完成 而不是通过移除来完成 作为问题的一个简单例子 我不想破坏爱尔兰名字 最好的方法是什么 是否有任何库
  • 将图像绘制到面板控件上会在调整大小时产生伪像

    目前我正在尝试做我认为简单的任务 将图像绘制到整个区域Panel control在 Windows 窗体中 请暂时忽略我可以使用BackgroundImage财产 要绘制的图像如下所示 IE 一个黄色框 周围有 1 像素蓝色框 为了绘图 我
  • 在 GCC 中编译而不生成输出文件

    gcc c somefile c无需链接即可编译并生成相应的somefile o 是否可以编译文件gcc不生成任何输出文件 我知道还有其他方法可以实现此目的 但我很好奇是否有一个标志专门用于正在经历寻找错误 警告的源代码 您可能会喜欢 fs
  • 在 Joomla 框架内强制 PHP 下载文件

    我有一些 PHP 代码 可以在数据库上运行查询 将结果保存到 csv 文件 然后允许用户下载该文件 问题是 csv 文件包含实际 csv 内容周围的页面 HTML 我已经在这里阅读了所有相关问题 包括this one 不幸的是 我的代码存在
  • 从自定义源(非标准 XML)加载 WCF 配置(针对服务器 + 客户端)

    我一直在尝试找到一种方法从备用源 而不是标准的 web config app config 加载我的 WCF 服务配置 巨大的 XML 配置数据 BLOB 我们在受限环境中运行 无法访问服务器的文件系统 因此我们无法自己对 WCF 配置进行
  • 升级到 Gradle 5 后 Querydsl 注释处理器问题

    我有一个 gradle 脚本 它从 Mongo 带注释的实体生成 querydsl 类 到目前为止它可以正常工作 但是升级到 Gradle 5 后我遇到了一个问题 What went wrong Execution failed for t
  • “id 无法解析或不是字段”错误?

    我不断收到此错误 我应该做吗id一个字段 我的代码是 public void onCreate Bundle icicle super onCreate icicle setContentView R layout main ImageVi
  • MySQL 和嵌套集:慢 JOIN(不使用索引)

    我有两张桌子 地区 CREATE TABLE localities id int 11 NOT NULL AUTO INCREMENT name varchar 100 NOT NULL type varchar 30 NOT NULL p