针对海量数据优化MySQL全外连接

2023-11-30

我们有以下 mysql 表(为了直奔主题而简化)

CREATE TABLE `MONTH_RAW_EVENTS` (
  `idEvent` int(11) unsigned NOT NULL,
  `city` varchar(45) NOT NULL,
  `country` varchar(45) NOT NULL,
  `ts` datetime NOT NULL,
  `idClient` varchar(45) NOT NULL,
  `event_category` varchar(45) NOT NULL,
  ... bunch of other fields
  PRIMARY KEY (`idEvent`),
  KEY `idx_city` (`city`),
  KEY `idx_country` (`country`),
  KEY `idClient` (`idClient`),
) ENGINE=InnoDB;

CREATE TABLE `compilation_table` (
  `idClient` int(11) unsigned DEFAULT NULL,
  `city` varchar(200) DEFAULT NULL,
  `month` int(2) DEFAULT NULL,
  `year` int(4) DEFAULT NULL,
  `events_profile` int(10) unsigned NOT NULL DEFAULT '0',
  `events_others` int(10) unsigned NOT NULL DEFAULT '0',
  `events_total` int(10) unsigned NOT NULL DEFAULT '0',
  KEY `idx_month` (`month`),
  KEY `idx_year` (`year`),
  KEY `idx_idClient` (`idClient`),
  KEY `idx_city` (`city`)
) ENGINE=InnoDB;

MONTH_RAW_EVENTS包含近 20M 行,用户在网站中执行操作,大小近 4GB

compilation_table每个月都有一个客户/城市摘要,我们用它在网站上实时显示统计数据

我们每月处理一次统计信息(从第一个表到第二个表),并且我们正在尝试优化执行此类操作的查询(因为到目前为止,我们正在 PHP 中处理所有内容,这需要很长时间)

这是我们提出的查询,它似乎在使用小数据子集时完成了工作, 全套数据处理时间超过6小时的问题

INSERT INTO compilation_table (idClient,city,month,year,events_profile,events_others)


    SELECT  IFNULL(OTHERS.idClient,AP.idClient) as idClient,
            IF(IFNULL(OTHERS.city,AP.city)='','Others',IFNULL(OTHERS.city,AP.city)) as city,
        01,2014,
    IFNULL(AP.cnt,0) as events_profile,
        IFNULL(OTHERS.cnt,0) as events_others           

    FROM
    (
        SELECT idClient,CONCAT(city,', ',country) as city,count(*) as cnt 
        FROM `MONTH_RAW_EVENTS` WHERE `ts`>'2014-01-01 00:00:00' AND `ts`<='2014-01-31 23:59:59'
        AND `event_category`!='CLIENT PROFILE'
        GROUP BY idClient,city
    ) as OTHERS
 LEFT JOIN 
    (
        SELECT idClient,CONCAT(city,', ',country) as city,count(*) as cnt 
        FROM `MONTH_RAW_EVENTS` WHERE `ts`>'2014-01-01 00:00:00' AND `ts`<='2014-01-31 23:59:59'
        AND `event_category`='CLIENT PROFILE'
        GROUP BY idClient,city
    ) as CLIPROFILE 
    ON CLIPROFILE.city=OTHERS.city and CLIPROFILE.idClient=OTHERS.idClient

 UNION

    SELECT  IFNULL(OTHERS.idClient,CLIPROFILE.idClient) as idClient,
            IF(IFNULL(OTHERS.city,CLIPROFILE.city)='','Others',IFNULL(OTHERS.city,CLIPROFILE.city)) as city,
            01,2014,
            IFNULL(CLIPROFILE.cnt,0) as events_profile,
            IFNULL(OTHERS.cnt,0) as events_others           
    FROM
    (
        SELECT idClient,CONCAT(city,', ',country) as city,count(*) as cnt 
        FROM `MONTH_RAW_EVENTS` WHERE `ts`>'2014-01-01 00:00:00' AND `ts`<='2014-01-31 23:59:59'
        AND `event_category`!='CLIENT PROFILE'
        GROUP BY idClient,city
    ) as OTHERS
 RIGHT JOIN 
    (
        SELECT idClient,CONCAT(city,', ',country) as city,count(*) as cnt 
        FROM `MONTH_RAW_EVENTS` WHERE `ts`>'2014-01-01 00:00:00' AND `ts`<='2014-01-31 23:59:59'
        AND `event_category`='CLIENT PROFILE'
        GROUP BY idClient,city
    ) as CLIPROFILE 
    ON CLIPROFILE.city=OTHERS.city and CLIPROFILE.idClient=OTHERS.idClient

我们想要做的是 Mysql 中的 FULL Outer Join,因此查询的基本模式如下:这里提出的

我们如何优化查询?我们一直在尝试不同的索引,不断地改变东西,但8小时后仍然没有完成运行,

MySQL服务器是Percona MySQL 5.5专用机器,具有2cpu、2GB RAM和SSD磁盘, 我们使用 Percona 工具优化了此类服务器的配置,

任何帮助将非常感激,

thanks


您正在执行 UNION,这会导致 DISTINCT 处理。

通常最好将 Full Join 重写为 Left Join 加上 Right Join 的不匹配行(如果是正确的 1:n join)

OTHERS LEFT JOIN CLIPROFILE 
ON CLIPROFILE.city=OTHERS.city and CLIPROFILE.idClient=OTHERS.idClient
union all
OTHERS RIGHT JOIN CLIPROFILE 
ON CLIPROFILE.city=OTHERS.city and CLIPROFILE.idClient=OTHERS.idClient
WHERE OTHERS.idClient IS NULL 

此外,您可能会在连接临时表之前将派生表的结果具体化,因此计算只完成一次(我不知道MySQL的优化器是否足够聪明,可以自动执行此操作)。

另外,将城市/国家作为单独的列进行分组和加入并执行以下操作可能会更有效CONCAT(城市,',',国家) 作为城市在外层台阶中。

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

针对海量数据优化MySQL全外连接 的相关文章

  • 部署 dacpac 所需的权限

    我正在尝试使用 sqlpackage exe 在租户上部署 dacpac 目前 我正在向将部署此功能的帐户授予 SysAdmin 或 db owner 权限 并且它工作正常 但在生产中 如果目标租户数据库属于其他应用程序 我可能无法获得这些
  • 多级排序

    我有一个表 其中包含一些记录 其中包含名称 评级等字段 我首先想要根据评级将结果限制为 20 进行排序 然后在此结果集上想要进一步应用基于名称的排序 我知道要排序我们需要使用像这样的查询 Select from table order by
  • 如何编写 bash 函数来包装另一个命令?

    我正在尝试编写一个函数包装器mysql command If my cnf存在于 pwd 中 我想自动附加 defaults file my cnf到命令 这就是我正在尝试的 function mysql if e my cnf then
  • 1:1 关系中的双向外键约束

    我正在使用 MySQL 数据库 在我的关系数据模型中 我有两个相互 1 1 关联的实体 在我的架构中 通过将 FK 字段放入两个表之一中来建立 1 1 关系 该字段与另一个表的 PK 相关 两个表都有 PK 并且都是自动递增的 BIGINT
  • 创建rest api url以连接mysql数据库

    我想学习如何创建一个rest api url 以便我可以使用该url获取信息并将信息发布到我的mysql数据库中 谷歌搜索了很多并阅读了各种文章 但没有找到任何精确的内容可以学习 所有内容均以 about api 开头 以已创建的其余 ur
  • MySQL:空间查询查找纬度/经度点是否位于给定边界内

    我正在研究谷歌地图搜索功能 其目的是找出 地理位置 点是否位于多边形内 如下图所示 我使用带有 Spatial 扩展的 mysql 5 6 20 我知道它内置有用的几何函数 因此我可以直接从数据库查询地理编码位置 我的目的是熟悉地理空间函数
  • 有没有办法只安装mysql客户端(Linux)? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 有没有不需要安装整个mysql db安装包的Linux mysql命令行工具 我想做的是从服务器 1 应用程序服务器 执行将在服务器 2
  • 安装后步骤未成功完成 MySQL Mac OS Sierra

    pyEnv Anants MacBook Pro litibackend anantchandra brew postinstall mysql gt Postinstalling mysql gt usr local Cellar mys
  • 如何在SqlAlchemy中执行“左外连接”

    我需要执行这个查询 select field11 field12 from Table 1 t1 left outer join Table 2 t2 ON t2 tbl1 id t1 tbl1 id where t2 tbl2 id is
  • 如何将 SQL“LIKE”与 LINQ to Entities 结合使用?

    我有一个文本框 允许用户指定搜索字符串 包括通配符 例如 Joh Johnson mit ack on 在使用 LINQ to Entities 之前 我有一个存储过程 该存储过程将该字符串作为参数并执行以下操作 SELECT FROM T
  • oracle中的区间函数

    Query SELECT INTERVAL 300 month INTERVAL 54 2 year to month INTERVAL 11 12 10 1234567 hour to second FROM DUAL 上述查询的输出是
  • 优化 LINQ 查询 - 如何缩短执行时间?

    我想知道是否有一个好的方法来优化我的 LINQ 查询 我正在使用类似于以下内容的 LINQ 查询从数据库检索数据 PKs is a list of integers var import context table Where x gt P
  • 选择 mysql 枚举的 php 函数

    因此 我创建了一个函数 它将从数据库中的枚举字段中提取值
  • MySQL 使用 DATE_ADD 设置 DATE 列的默认值?

    我正在尝试使用表达式将 DATE 列添加到具有 DEFAULT DATE 值的表中 ALTER TABLE wp ezts project params ADD est completion DATE NOT NULL DEFAULT DA
  • 更改“Mysql 行大小太大”的限制

    我如何更改限制 行大小太大 gt 8126 将某些列更改为 TEXT 或 BLOB 或使用ROW FORMAT DYNAMIC or ROW FORMAT COMPRESSED可能有帮助 在当前行格式中 BLOB768 字节的前缀内联存储
  • MySql 复合索引

    我们使用 MySql 作为我们的数据库 以下查询在 mysql 表 大约 2500 万条记录 上运行 我在这里粘贴了两个查询 查询运行得太慢 我想知道更好的复合索引是否可以改善这种情况 你知道最好的综合指数是什么吗 并建议我这些查询是否需要
  • PLSQL 中的时区转换

    我需要将系统日期和时间转换为特定时区 例如东部时间 我无法假设我当前的时区 如何在plsql中转换它 请帮我 假设你有一个TIMESTAMP WITH TIME ZONE 例如systimestamp 您可以使用AT TIME ZONE句法
  • 尝试在 Mac OSX 上的 virtualenv 和 MySQL 中安装 Django CMS 时出错

    当我尝试使用 virutalenv 安装带有 MySQL 的 django CMS 时 出现以下错误 RuntimeError maximum recursion depth exceeded Users ethan Sites env b
  • 像搜索一样在mysql中包含空格

    我在某些情况下使用 mysql like 关键字时遇到问题 我的要求是这样的 首先 当我搜索时 ABC 结果应该找到ABC and ABCdef但不是xyzABCdef or xyzABC 乍一看使用起来很简单ABC 但在我搜索时的情况 h
  • 在 Java Web 应用程序中获取 DataSource 资源

    我的 context xml 文件中有以下资源标记

随机推荐