通过在彼此之间嵌套子查询来解决 MySQL 中 61 个表 JOIN 的限制

2023-12-10

我发现你可以通过使用子查询来绕过 MySQL 中 61 个表连接的限制。https://stackoverflow.com/a/20134402/2843690

我正在想办法easily在我正在开发的程序中使用它来从 Magento 获取详细的产品列表(但我认为这个问题的答案可能适用于涉及 eav 的很多情况)。需要连接的表看起来像这样:

catalog_product_entity
+-----------+----------------+
| entity_id | entity_type_id |
+-----------+----------------+
|         1 |              4 |
|         2 |              4 |
|         3 |              4 |
|         4 |              4 |
|         5 |              4 |
|         6 |              4 |
|         7 |              4 |
|         8 |              4 |
|         9 |              4 |
+-----------+----------------+

catalog_product_entity_int
+----------+----------------+--------------+-----------+-------+
| value_id | entity_type_id | attribute_id | entity_id | value |
+----------+----------------+--------------+-----------+-------+
|        1 |              4 |            2 |         1 |   245 |
|        2 |              4 |            3 |         1 |   250 |
|        3 |              4 |            4 |         1 |   254 |
|        4 |              4 |            2 |         2 |   245 |
|        5 |              4 |            3 |         2 |   249 |
|        6 |              4 |            4 |         2 |   253 |
|        7 |              4 |            2 |         3 |   247 |
|        8 |              4 |            3 |         3 |   250 |
|        9 |              4 |            4 |         3 |   254 |
+----------+----------------+--------------+-----------+-------+

eav_attribute
+--------------+----------------+----------------+--------------+
| attribute_id | entity_type_id | attribute_code | backend_type |
+--------------+----------------+----------------+--------------+
|            1 |              4 | name           | varchar      |
|            2 |              4 | brand          | int          |
|            3 |              4 | color          | int          |
|            4 |              4 | size           | int          |
|            5 |              4 | price          | decimal      |
|            6 |              4 | cost           | decimal      |
|            7 |              4 | created_at     | datetime     |
|            8 |              3 | name           | varchar      |
|            9 |              3 | description    | text         |
+--------------+----------------+----------------+--------------+

eav_attribute_option
+-----------+--------------+
| option_id | attribute_id |
+-----------+--------------+
|       245 |            2 |
|       246 |            2 |
|       247 |            2 |
|       248 |            3 |
|       249 |            3 |
|       250 |            3 |
|       251 |            4 |
|       252 |            4 |
|       253 |            4 |
|       254 |            4 |
+-----------+--------------+

eav_attribute_option_value
+----------+-----------+-------------------+
| value_id | option_id |       value       |
+----------+-----------+-------------------+
|       15 |       245 | Fruit of the Loom |
|       16 |       246 | Hanes             |
|       17 |       247 | Jockey            |
|       18 |       248 | White             |
|       19 |       249 | Black             |
|       20 |       250 | Gray              |
|       21 |       251 | Small             |
|       22 |       252 | Medium            |
|       23 |       253 | Large             |
|       24 |       254 | Extra Large       |
+----------+-----------+-------------------+

我正在编写的程序生成的 SQL 查询如下所示:

SELECT cpe.entity_id
, brand_int.value as brand_int, brand.value as brand
, color_int.value as color_int, color.value as color
, size_int.value as size_int, size.value as size

FROM catalog_product_entity as cpe

LEFT JOIN catalog_product_entity_int as brand_int
ON (cpe.entity_id = brand_int.entity_id
AND brand_int.attribute_id = 2)
LEFT JOIN eav_attribute_option as brand_option
ON (brand_option.attribute_id = 2
AND brand_int.value = brand_option.option_id)
LEFT JOIN eav_attribute_option_value as brand
ON (brand_option.option_id = brand.option_id)

LEFT JOIN catalog_product_entity_int as color_int
ON (cpe.entity_id = color_int.entity_id
AND color_int.attribute_id = 3)
LEFT JOIN eav_attribute_option as color_option
ON (color_option.attribute_id = 3
AND color_int.value = color_option.option_id)
LEFT JOIN eav_attribute_option_value as color
ON (color_option.option_id = color.option_id)

LEFT JOIN catalog_product_entity_int as size_int
ON (cpe.entity_id = size_int.entity_id
AND size_int.attribute_id = 4)
LEFT JOIN eav_attribute_option as size_option
ON (size_option.attribute_id = 4
AND size_int.value = size_option.option_id)
LEFT JOIN eav_attribute_option_value as size
ON (size_option.option_id = size.option_id)
;

编写生成查询的代码相对容易,而且查询也相当容易理解;然而,很容易达到 61 个表连接的限制,我用现实生活中的数据做到了这一点。我相信数学表明 21 个整数类型属性将超出限制,而且这是在我开始添加 varchar、文本和小数属性之前。

所以我想出的解决方案是使用子查询来克服 61 个表的限制。

一种方法是将连接分组到包含 61 个连接的子查询中。然后所有的组都会加入。我想我可以弄清楚 sql 查询应该是什么样子,但编写代码来生成查询似乎很困难。还有一个进一步的(尽管是理论上的)问题,即如果有足够的属性,可能会再次违反 61 个表的限制。换句话说,如果我有62组61张表,就会出现MySQL错误。显然,可以通过将组分组为 61 来解决这个问题。但这只会使代码更加难以编写和理解。

我认为我想要的解决方案是将子查询嵌套在子查询中,这样每个子查询都使用 2 个表(或一个表和一个子查询)的单个联接。直观上,似乎为这种查询编写代码会更容易。不幸的是,思考这些查询应该是什么样子让我的大脑受伤。这就是为什么我需要帮助。

这样的 MySQL 查询会是什么样子?


您是对的,通过 EAV 设计连接太多属性可能会超出连接限制。即使在此之前,连接也可能存在实际限制,因为大量连接的成本呈几何级数越来越高。这有多糟糕取决于服务器的容量,但它可能比 61 低很多。

因此,查询 EAV 数据模型以生成结果,就好像它存储在传统关系模型(每个属性一列)中一样是有问题的。

解决方案:不要使用每个属性的联接来执行此操作,这意味着您不能期望纯粹使用 SQL 以传统的每个实体行格式生成结果。

我对 Magento 模式不太熟悉,但我可以从您的查询中推断出这样的事情可能有效:

SELECT cpe.entity_id
, o.value AS option
, v.value AS option_value
FROM catalog_product_entity AS cpe
INNER JOIN catalog_product_entity_int AS i 
  ON cpe.entity_id = i.entity_id AND i.attribute_id IN (2,3,4)
INNER JOIN eav_attribute_option AS o 
  ON i.value = o.option_id AND i.attribute_id = o.attribute_id
INNER JOIN eav_attribute_option_value AS v
  ON v.option_id = o.option_id;

The IN(2,3,4,...)谓词是您指定多个属性的地方。无需添加更多联接来获取更多属性。它们只是以行而不是列的形式返回。

这意味着您必须编写应用程序代码来获取此结果集的所有行并将它们映射到单个对象的字段中。

从 @Axel 的评论来看,听起来 Magento 提供了辅助函数来消耗结果集并将其映射到对象中。

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

通过在彼此之间嵌套子查询来解决 MySQL 中 61 个表 JOIN 的限制 的相关文章

  • PostgreSQL:左外连接语法

    我正在使用 PostgreSQL 8 4 6 和 CentOS 5 5 并有一个用户表 select from pref users where id DE2 id first name last name female avatar ci
  • MySQL 存储过程将值分配给 select 语句中的多个变量

    这是我的存储过程 我在为声明的变量赋值时遇到问题 当我执行它时 插入和更新命令工作正常 但声明变量的值保持为 0 但我在数据库中有一些价值 我怎样才能正确地做到这一点 BEGIN DECLARE PaidFee INT DEFAULT 0
  • ActiveRecord3死锁重试

    Rails 3 或 ActiveRecord 3 是否有任何插件可以复制旧版本死锁重试 http agilewebdevelopment com plugins deadlock retry插入 或者 该插件仍然适用于 Rails 3 吗
  • 显示表 FULLTEXT 索引列

    我希望运行一个查询 该查询将返回表中全文索引的列列表 该表采用 MyISAM 格式 我将使用 php 来构建查询 理想情况下 我会运行查询 它会返回信息 以便我可以构造一个以逗号分隔的列字符串 例如 名 姓 电子邮箱 这在 MySQL 中可
  • java mysql 准备好的语句

    我正在尝试使用 java 向数据库中进行简单的插入 它告诉我我的 sql 语法已关闭 但是 当我复制打印出来的字符串并将其放入 phpmyadmin 中的 sql 命令中时 它会正确执行该命令 并且我似乎无法弄清楚 java 中的字符串查询
  • 第三个下拉菜单不从数据库填充

    我有以下 Index php
  • Mysql 检索所有有限制的行

    我想检索特定用户的所有行 限制为 0 x 所以我只是想问是否有任何方法可以检索 mysql 中的所有行 而不调用返回 x 的 count id 的方法 而不重载现有函数 该函数在查询中根本没有限制 与我们的 string Relace 功能
  • 如何在Mysql中仅将不同的值从一个表复制到另一个表?

    我有一个大约 2 5GB 的 MySql 数据库 表 A 具有以下列 anoid query date item rank url 我刚刚创建了另一个仅包含列的表 b query and date 我想在查询列中插入所有不同的记录 及其各自
  • MYSQL 区分大小写的 utf8 搜索(使用 hibernate)

    我的登录表具有 utf8 字符集和 utf8 排序规则 当我想要检查用户名并检索该特定用户名的其他信息时 hql 查询会为我提供小写和大写相同的结果 我应该如何处理适用于案例的 HQL 查询 我使用 Mysql 5 和 java hiber
  • Magento - 检查 cms 页面

    我想通过 php 检查页面是否是 Magento 中的 cms page 我需要不同的 cms 页面面包屑 所以我尝试在一个条件下做到这一点 但我不知道如何或在哪里查看 到目前为止 这是我的 breadcrumbs phtml p some
  • 如何正确转义mysql?

    我刚刚发现如果我写 select from tbl where name like foo 然后添加 foo 作为参数及其值 a 用户数据 它不会正确转义 我勒个去 它想要 a 即使我使用参数 我还是忍不住觉得我对 sql 注入持开放态度
  • Apache、PHP 和 MySQL 可移植吗?

    我可以在外部硬盘上运行 Apache PHP 和 MySQL 吗 我需要这个 因为我在不同的地方工作 计算机 有时我没有安装和配置所有使用的应用程序 当然可以 XAMPP http www apachefriends org en xamp
  • 免费 PHP 登录库 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何使用 vitess 仅对特定表进行分片

    我创建了一个包含三个表的未分片键空间 现在我想对前两个表的键空间进行分片 但不想对第三个表进行分片 如何才能做到这一点 Vitess 文档不包含任何与此相关的信息或示例 请帮忙 Thanks vitess 中的垂直分片与水平分片类似 您应该
  • Mysql 将 int 转换为 MAC

    我有一些数据可以转换 其中有 2 列 其中一列有 IP 它包含整数值 我在 mysql 查询中使用了以下函数 是否有一个函数可以用来转换我的 mac 列 其中包含整数和数据类型是bigint to MAC地址 SELECT INET NTO
  • PDO PHP 连接,致命错误

    我的连接类 firstcode php class DB functions public db function construct try db new PDO mysql localhost dbname xxx charset ut
  • Bugzilla 中分离客户端的基本权限

    我正在尝试配置一个 Bugzilla 实例 这将允许我的客户登录并为其正在开发 维护的网站提交错误 例如 我创建了 2 个名为 TestProject TestProject2 的产品和一个名为 TestClient 的用户 我想要实现的是
  • 如何在 Play java 中创建数据库线程池并使用该池进行数据库查询

    我目前正在使用 play java 并使用默认线程池进行数据库查询 但了解使用数据库线程池进行数据库查询可以使我的系统更加高效 目前我的代码是 import play libs Akka import scala concurrent Ex
  • PayPal 网关已拒绝请求。安全标头无效(#10002:安全错误 Magento

    在 magento 中增加 PayPal 预付款 我已填写 magento admin 中的所有凭据 但是当我进入前端并单击 pay pal 按钮时 它给出了 PayPal 网关已拒绝请求 安全标头无效 10002 安全错误 我用谷歌搜索了
  • 在 MySQL 中存储表情符号的编码问题:如何使用 Prisma ORM 在 NodeJS 中定义字符排序规则?

    亲爱的 Nodejs 专家和数据库专家 我们在 MySQL 数据库中存储表情符号和其他特殊字符时遇到问题 我们使用 Prisma 得到一个错误 这是我们使用的 ORM 参数无法从排序规则 utf8 general ci 转换为 utf8mb

随机推荐

  • 如何使用 Selenium WebDriver 和 Java 查找损坏的链接

    我想验证网站上的损坏链接 并且我正在使用以下代码 public static int invalidLink String currentLink String temp public static void main String arg
  • 如何禁用文本选择突出显示

    对于作用类似于按钮的锚点 例如 此 Stack Overflow 页面侧边栏上标题为问题 Tags and Users 或选项卡 是否有 CSS 标准方法可以在用户意外选择文本时禁用突出显示效果 我意识到这可以用 JavaScript 来完
  • 如何使用 C# 从另一个表单按下按钮?

    我有两种形式 Form1 进行屏幕截图 Form2 有 2 个按钮来操作 form1 创建的屏幕截图 Form1 还有一个 隐藏 按钮 其中包含保存屏幕截图的方法 我的问题 如何从form2中单击form1的按钮 和 如何检查 form1
  • 如何编写正则表达式来仅匹配数字、字母和破折号?

    我需要一个只接受以下内容的表达式 数字 普通字母 无特殊字符 空格也是不允许的 例子 正则表达式应该匹配 this is quite alright 不应该匹配 this is not so lright 您可以使用 A Za z0 9 这
  • Excel - 将一个范围内的数据匹配到另一个范围内,并从匹配数据右侧的单元格中获取值

    我不太擅长 Excel 公式 我正在尝试弄清楚如何首先检查列中是否存在单元格值 如果存在 则获取下一个单元格的值 具体来说 我有一系列细胞 从 B31 到 B39 我想要做的是查看这些值是否出现在单元格 F3 到 F12 中 如果出现 则将
  • WebGL等角投影

    好吧 这里要疯了 我正在做一些 WebGL 我正在尝试制作一个等距立方体 我不想使用 Three js 我想首先了解我的代码出了什么问题 我一直在研究 我能找到的唯一教程似乎是针对 OpenGL 的 无论如何 这是我的drawScene函数
  • 查询缓存不起作用

    我已经打开query cache 并为其分配内存 query cache limit 1048576 query cache min res unit 4096 query cache size 16777216 query cache t
  • 如何将多个 actionCreators 包装到一个 props 中?

    我收到以下错误 Uncaught TypeError this props dispatch is not a function 这是我的组件 import React from react import PropTypes from pr
  • 如何更改站点的 IIS Express 端口

    我想在从 Visual Studio 进行调试时更改网站运行的端口号 我正在使用 Visual Studio 2012 并且我正在为我的项目使用 ASP NET MVC 4 我想更改端口 随机端口或固定端口任何人都可以工作 只需更改端口即可
  • Django 使用 AJAX 动态 HTML 表刷新

    首先 我是 Django 新手 并且对 AJAX 和 jQuery 几乎完全不熟悉 我在本地开发 所以我试图实现一个 HTML 表 在 AJAX 的帮助下每 X 秒动态刷新一次 没有页面刷新 但我似乎无法让我的代码工作 我已经使用过这个问题
  • git:查找哪个合并将提交到当前分支

    我有许多分支 它们会定期合并 即我们可以将 A 合并到 B 中 然后将 B 合并到 C 中 然后将 A 合并到 D 中 然后将 D 合并到 C 中 等等 假设我有一个提交 X 我知道它最初是在A中引入的 然后以某种方式合并到C中 我在执行g
  • jQuery,按属性值选择,添加新属性

    我的 HTML 中有一个锚点 它有一个带有值的页面属性 因此 每次单击它时 我都会在 js 中使用页面属性值 现在我想设置一个带有背景颜色的样式属性来显示某个元素被选中 因此 我必须按页面属性选择元素 并向 a 元素添加一个带有值的新属性
  • 在 @FetchRequest 中输入一个动态值,以从 SwiftUI 中的核心数据中获取单个实体

    我在这里看到了相同类型的错误 但使用了不同类型的代码 所以我认为最好就此上下文提出一个新问题 我试图通过尝试传递一个字符串变量 用作查找该实体的键 来从核心数据中 查找特定实体 title into FetchRequest 这是我使用过的
  • BulkInsertCommand 在 Sync Framework 2.1 中失败

    有时 当我尝试使用 Sync Framework 2 1 从 SQL Express 同步到 SQL Server 时 会收到以下错误 一旦客户端收到此错误 他们必须重新初始化作用域 语法不会有任何问题 比如错误状态 因为它在很长一段时间内
  • 发布同名nuget包时在.net vNext中引用本地项目

    我正在尝试在 VS 2015 中使用新的 vNext 项目类型构建一个包 我想在同一解决方案 不是 vNext 中引用一个项目 但它试图为该项目找到一个 nuget 包 而不是直接引用它 我究竟做错了什么 version 1 0 0 dep
  • 在 Dreamweaver CS 5.5 中设置 codeigniter

    我正在寻找有关如何在 Dreamweaver CS 5 5 中设置代码点火器项目的信息 并像 Zend 框架一样使用代码提示 我成功地在 Dreamweaver CS5 5 中设置了 code igniter 方法是下载最新版本的 code
  • 使用 Python 3.6 抓取 Duckduckgo

    一个简单的问题 我可以从 duckduckgo 搜索的第一页抓取结果 然而 我正在努力进入第二页和后续页面 我已将 Python 与 Selenium Webdriver 结合使用 这对于首页结果来说效果很好 我用来抓取第一页的代码是 re
  • iPhone6(无显示缩放模式)UIMenuController 被截断

    我有一个问题UIMenuController在我的 iPhone 6 上 当我使用标准显示模式并且设备处于横向模式时 在 iPhone 6 Plus 上 两种模式都会出现问题 也许这取决于屏幕分辨率 在这种情况下 UIMenuControl
  • Keras 后端 - ImportError:无法导入名称 ctc_ops

    我已经安装了 keras 但是当我编写 import keras 时 出现错误 导入错误 无法导入名称 ctc ops 我想将后端从张量流更改为 theano 但找不到此处提到的 keras json https keras io back
  • 通过在彼此之间嵌套子查询来解决 MySQL 中 61 个表 JOIN 的限制

    我发现你可以通过使用子查询来绕过 MySQL 中 61 个表连接的限制 https stackoverflow com a 20134402 2843690 我正在想办法easily在我正在开发的程序中使用它来从 Magento 获取详细的