通过大量连接优化 MySQL 查询

2023-12-09

我目前运行一个网站,该网站在列表中跟踪最新的分数和评级。该列表有数千个经常更新的条目,并且该列表应该可以按这些分数和评级列进行排序。

目前获取这些数据的 Mysql 看起来像(大致):

SELECT e.*, SUM(sa.amount) AS score, AVG(ra.rating) AS rating
FROM entries e 
LEFT JOIN score_adjustments sa ON sa.entry_id = e.id
    HAVING sa.created BETWEEN ... AND ... 
LEFT JOIN rating_adjustments ra ON ra.entry_id = e.id
    HAVING ra.rating > 0 
ORDER BY score 
LIMIT 0, 10

表格所在位置(简化):

entries:
    id: INT(11) PRIMARY
    ...other data...

score_adjustments:
    id: INT(11), PRIMARY
    entry_id: INT(11), INDEX, FOREIGN KEY (entries.id)
    created: DATETIME
    amount: INT(4)

rating_adjustments:
    id: INT(11), PRIMARY
    entry_id: INT(11), INDEX, FOREIGN KEY (entries.id)
    rating: DOUBLE

大约有300,000score_adjustments条目数量每天增加约 5,000 个。这rating_adjustments大约是1/4。

现在,我不是 DBA 专家,但我猜想打电话SUM() and AVG()一直都不是一件好事——尤其是当sa and ra包含数十万条记录 - 对吗?

我已经对查询进行了缓存,但我希望查询本身能够快速 - 但仍尽可能保持最新。我想知道是否有人可以分享任何解决方案来优化像这样的繁重的联接/聚合查询?如有必要,我愿意进行结构性改变。

EDIT 1

添加了有关查询的更多信息。


你的数据很糟糕聚集的.

InnoDB 将存储具有“接近”的 PK 物理上靠近的行。由于您的子表使用代理 PK,因此它们的行将随机存储。当需要对“主”表中的给定行进行计算时,DBMS 必须跳过所有位置以从子表中收集相关行。

尝试使用更“自然”的键,而不是代理键,并将父级的 PK 置于前沿,类似于:

score_adjustments:
    entry_id: INT(11), FOREIGN KEY (entries.id)
    created: DATETIME
    amount: INT(4)
    PRIMARY KEY (entry_id, created)

rating_adjustments:
    entry_id: INT(11), FOREIGN KEY (entries.id)
    rating_no: INT(11)
    rating: DOUBLE
    PRIMARY KEY (entry_id, rating_no)

注意:这假设created的分辨率足够好并且rating_no添加了多个评级以允许每个评级entry_id。这只是一个例子 - 您可以根据您的需要改变 PK。

这将“强制”属于同一行entry_id物理上靠近存储,因此只需对 PK/聚类键进行范围扫描即可计算 SUM 或 AVG,并且只需很少的 I/O。

或者(例如,如果您使用不支持集群的 MyISAM),cover带索引的查询,因此在查询期间根本不会触及子表。


最重要的是,您可以对设计进行反规范化,并将当前结果缓存在父表中:

  • 将 SUM(score_adjustments.amount) 存储为物理字段,并在每次插入、更新或删除行时通过触发器调整它score_adjustments.
  • 将 SUM(评级调整.评级) 存储为“S”andCOUNT(评级调整.评级)为“C”。当添加一行时rating_adjustments,将其添加到 S 并递增 C。在运行时计算 S/C 以获得平均值。类似地处理更新和删除。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

通过大量连接优化 MySQL 查询 的相关文章

  • AND OR 导致显示的结果多于应有的结果

    我正在尝试显示特定时间范围内匹配的结果 效果很好 但是 我想添加一个子句 表示显示的结果必须是 party type1 or 2 所以我这样做了 WHERE start datetime gt DATE START SELECTED AND
  • 我需要使用 cron 作业每 30 分钟恢复一次数据库 (mysql)

    我是 cron 作业的新手 我需要每 30 分钟恢复一次数据库 mysql 是否有一个 cron 作业命令可以从已压缩的 sql 文件恢复数据库 或者我是否需要创建一个 php 脚本来执行此操作并创建一个 cron 作业来每三十分钟调用此脚
  • Hibernate 中基本类型的 ArrayList

    我有一个关于整数数组列表或一般基本类型的问题 假设我正在设计一个 POS 程序 每种产品可能有多个价格 假设我可以用以下方式表示价格值ints 并在Product类我有领域ArrayList
  • 如何在 C# 中从 MySQL 检索tinyint 数据类型?

    因此 在 C 中 每当我从 MSSQL 数据库检索 tinyint 时 我都会使用以下转换 int byte reader MyField 然而 这种转换似乎在 MySQL 中不起作用 我尝试过的 byte reader MyField 并
  • MySQL:长表与宽表

    哪种数据库表设计更高效 就查询性能而言 长表还是宽表 即 这个 id size price 1 S 12 4 1 M 23 1 1 L 33 3 2 S 3 3 2 M 5 3 2 L 11 0 与此相对 id S M L 1 12 4 2
  • 如何在Java中使用准备好的语句进行选择查询?

    我曾多次尝试使用准备好的语句 但它返回 SQL 异常 这是我的代码 public ArrayList
  • JDBC 插入错误

    我正在尝试使用 jdbc 将一些数据插入到我的数据库中 我使用了正确的表 数据库名称和参数 一切都经过检查 Code public static void main String args throws IOException ClassN
  • 将 Wamp 服务器升级到 MySQL 8.0.15

    因此 我最近在几个月前安装了 WampServer 并预装了 mySQL 5 7 但我想利用 mySQL 8 附带的 NoSQL 功能 为了更新它 我下载了最新的MySQL版本 将文件夹解压到wamp64的bin目录中 然后 我从 5 7
  • 如何限制 SQLite / MySQL 中的列值

    我想限制表中的列值 例如 列值只能是car or bike or van 我的问题是如何在 SQL 中实现这一点 在数据库端执行此操作是一个好主意还是应该让应用程序限制输入 我还打算在将来添加或删除更多值 例如 truck 我使用的数据库类
  • 如何从准备好的语句中获取标量结果?

    是否可以将准备好的语句的结果设置为变量 我正在尝试创建以下存储过程 但失败了 第 31 行出现错误 1064 42000 您的 SQL 语法有错误 检查与您的 MySQL 服务器版本相对应的手册 了解在 stmt USING m c a 附
  • MYSQL:如何从姓氏中找到player_id?

    我现在尝试使用非标准化 摘要 表中的数据填充 testMatch 表 如下 测试匹配表 Field Type Null Key Default Extra match id int 11 NO PRI NULL match date dat
  • MySQL 多索引与多列索引进行搜索

    在我正在编写的软件中 它能够搜索给定的表以获取信息 搜索表单有 5 个字段 当然所有字段都对应于表中的不同列 但所有字段都是可选的 我的问题是关于多列索引是否有效以及为其构建查询的正确方法 如果我有一个跨 5 列的索引 并且我构建了一个查询
  • 为什么java字符串在MYSQL中不保存为UTF-8?

    message new String round id getBytes UTF 8 conn DriverManager getConnection jdbc mysql host db useUnicode true character
  • mysql - 如果日期不与现有日期重叠,则将日期范围插入日期列

    我有以下表结构 表名 available id autoincremetn acc id start date end date 1 175 2015 05 26 2015 05 31 2 175 2015 07 01 2015 07 07
  • 无法将代码优先迁移应用到 mysql 数据库

    我正在使用 EF 代码优先模型开发 asp net mvc 我正在尝试首先使用 EF 代码将迁移应用到我的项目中 我正在使用 MySql 数据库 目前我使用的是 EF 4 3 1 版本和 6 6 4 0 版本的 mysql Connecto
  • JS 无法查询 MySQL 数据库。错误:connection.query 不是函数

    尝试查询我的 mySQL 数据库 但我不能 因为我得到了TypeError connection query is not a function错误 有谁知道为什么吗 我不知道为什么会发生这种情况 数据库 js const fs requi
  • PHP 和 MySQLi 中没有选择数据库错误[重复]

    这个问题在这里已经有答案了 我必须从 MySQL 数据库中选择数据 我一直在寻找答案 但仍然没有找到 我正在学习W3School http www w3schools com php php mysql select asp 我的 MySQ
  • 浏览器关闭后从数据库中删除

    我正在开发一个电子商务应用程序 但问题是 当用户将产品添加到购物车并在订购前关闭浏览器时 购物车会带走所有产品 所有购物车项目都保存在表中 如果用户关闭浏览器而不订购 我只想刷新购物车 您可以使用 Javascript 事件捕获浏览器关闭并
  • 保存用户的身高和体重

    我应该如何将用户的身高和体重存储在MySQL数据库中 以便我可以使用这些信息来查找特定身高或体重内的用户 另外 我需要能够以英制或公制显示此信息 我的想法是存储以厘米为单位的身高和以公斤为单位的体重信息 我更喜欢公制而不是英制 我什至可以让
  • 用于分页的php示例脚本[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 任何人都可以建议一个好的分页 php 脚本 其中人们想要分页显示数据库中的大量项目 以下链接可以帮助您

随机推荐

  • Selenium 中的数据提供者与 TestNG 不匹配

    我正在用 selenium 编写以下代码 并显示以下错误 请让我知道问题出在哪里 导入 org testng annotations DataProvider 导入 org testng annotations Test public cl
  • Javascript 正则表达式:如果前面有 href=" 则排除结果

    我正在努力将 Javascript 中的字符串替换为正则表达式匹配模式 我想替换 的所有匹配项 myparam 被 span 标签包围 这是可行的 参见下面的代码 但我想防止在匹配前面有 href 时进行替换 例子 href myparam
  • 使 JSP 中的 scriptlet 无效

    我试图通过在部署描述符中编写以下代码来使 scriptlet 无效 但脚本仍然被执行
  • 将字段序列化为 json

    我需要将 JSON 正文发送到 REST 服务 不幸的是 服务相当旧 我需要发送一个包含 JSON 字符串字段的 POJO 所以它看起来像这样 class SomeData int id SomePojo jsonField 所以 Some
  • Nginx 浏览器使用别名进行缓存

    我正在尝试使用 Django 在 nginx 上设置浏览器缓存 我的 nginx 配置文件的静态文件的当前 工作 配置如下 server listen 443 ssl server name SERVER ssl certificate e
  • 如何阻止从浏览器控制台访问 Firebase 实时数据库?

    我有这个 JavaScript 代码 用户可以使用他们的 Google 帐户登录我的应用程序 firebase db congifurations const config apiKey my api key authDomain my a
  • 在一行中输入用逗号分隔的 2 个变量

    可以输入2个数字吗int or float在一行中用逗号分隔 假设程序运行后会要求用户Enter a range 然后用户会输入2 3 所以变量范围是 2 3 据我所知range choice split 是唯一的办法 num1 num2
  • array:将一维数组的索引转换为多维数组的向量索引

    这将是一个很长的问题 请在阅读之前深呼吸 我想了解将一维数组的索引转换为多维数组的向量索引的最快算法是什么 让我们继续看一个例子来理解为什么我需要它 我有一个二维数组 Array i1 i2 i1 从 i1 b 0 运行到 i1 e 2 i
  • Android系统应用DEVICE_POWER权限错误

    我尝试使用goToSleep 让手机进入深度睡眠的方法 程序被安装到 system app 目录中 因此 Android 系统信息显示 它是一个系统应用程序 但如果我尝试调用 goToSleep 我会收到此错误 用户 10085 和当前进程
  • 如何在 spring-security 5.7 中配置 ldap,同时保留基本表单登录

    我正在尝试配置我的 webSecurity 以使用 ldap 和基本身份验证 jdbc 以及新的基于组件的安全配置 无 WebSecurityConfigurerAdapter 但我无法让它同时使用两者 所需的结果是 spring 第一次尝
  • Google Analytics Tracker 不适用于 Android 应用

    我已将 Google Analytics 纳入我的应用程序中 但是当我创建一个对象时Tracker追踪器不工作 我的一项活动中的代码 Override protected void onStart TODO Auto generated m
  • 如何为事件处理程序提供变量?

    当我绑定某些东西时 如何将变量赋予函数 举个简单的例子 def test self self MyTextCtrl Bind wx EVT TEXT self something AnyVariable def something self
  • 验证视图状态 MAC 失败 - “/”应用程序中的服务器错误

    当我访问我的托管 Web 应用程序时出现此错误 在 VS2008 C ASP NET 3 5 Framework 中 视图状态 MAC 验证失败 如果此应用程序由 Web Farm 或集群托管 请确保配置指定相同的validationKey
  • 覆盖 SemanticException [错误 10001]

    我想更改 hive 数据库中的 1000 个表 但其中一些表存在 有些不存在 当我执行该 sql 文件时 一旦发现表不存在 它就会从配置单元退出 所以请帮助我覆盖或跳过那些表不存在于配置单元中的查询 尝试这个配置参数 set hive cl
  • React Router V4 - 页面不会在更改的路由上重新渲染

    我正在构建一个小应用程序来学习 React 和 Meteor 要求用户输入一个位置 根据这个位置 用户被路由到一个新页面 该位置显示在页面顶部 以及基于该位置的数据库中的一些数据 还没有 这是我的 下一步 我将位置存储在组件的状态中 现在如
  • JavaScript - 如何提取 If/Else 语句中的字符串

    在搜索 imgNumber 变量后 我尝试使用 If Else 语句在屏幕上写入某些文本 由于某种原因 无论 imgNumber 变量中包含哪个文本 它都只写入字符串 cockroaches 此外 imgNumber 是一个随机字符串 它始
  • scala 中的闭包是如何实现的?

    创建函数时 如何将函数范围之外的变量拉入函数中 我尝试反编译 但我无法理解它 看起来它使用了 putfield putfield 是否创建一个指向对象引用的指针 答案是 这取决于 scala 2 11 版本可能会对此进行一些重大更改 希望
  • 显式 range-v3 decltype 计算结果为 void?

    我正在尝试获取范围的显式类型 将来我可能想将其存储为类中的字段 然而 由于某种原因 它评估为void include
  • @ManagedProperty 不反映更改并始终返回 null

    我试图将一个 sessionscoped bean 的值注入到 viewscoped bean 中 但它一直返回 null 这是一个片段 import javax faces application FacesMessage import
  • 通过大量连接优化 MySQL 查询

    我目前运行一个网站 该网站在列表中跟踪最新的分数和评级 该列表有数千个经常更新的条目 并且该列表应该可以按这些分数和评级列进行排序 目前获取这些数据的 Mysql 看起来像 大致 SELECT e SUM sa amount AS scor