繁体   English   中英

是否可以对视图进行分区,例如MySQL中的表?

[英]Is it possible to partition a view, like table in MySQL?

我已经从约10个表的UNION ALL子句创建了视图,并希望按日期范围对其应用一些搜索查询。 但是随着记录数量的增加,执行查询所需的时间会更长。 目前,该视图有20亿行。

表结构如下:

CREATE TABLE IF NOT EXISTS `tbl_queue_stats_0716` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `server_id` int(11) NOT NULL, 
    `uniqueid` varchar(100) DEFAULT NULL, 
    `queue_datetime` datetime NOT NULL, 
    `queue_timestamp` varchar(100) NULL, 
    `qname_id` int(11) NOT NULL, 
    `qagent_id` int(11) NOT NULL, 
    `qevent_id` int(11) NOT NULL, 
    `info1` varchar(100) DEFAULT NULL, 
    `info2` varchar(100) DEFAULT NULL, 
    `info3` varchar(100) DEFAULT NULL, 
    `info4` varchar(100) DEFAULT NULL, 
    `info5` varchar(100) DEFAULT NULL, 
    PRIMARY KEY (`id`)
);

表格是按月创建的,因此可以有tbl_queue_stats_0616,tbl_queue_stats_0516,tbl_queue_stats_0416之类的表格...

如果要将日期范围从2个月或更长时间开始搜索,我想对多个表应用搜索查询。

搜索查询如下所示:

select  server_id,server_name,queue_id,queue_name,qevent_id,event,
        count(id) as cnt,sum(info1) as info1, sum(info2) as info2,
        sum(info3) as info3, sum(info4) as info4, sum(info5) as info5,
        max(cast(info2 AS SIGNED)) as max_info2,
        max(cast(info3 AS SIGNED)) as max_info3
   from
      ( SELECT  a.server_id as server_id,e.server_name as server_name,
                a.id,a.`queue_datetime`, b.agent, a.qname_id as queue_id ,
               c.queue as queue_name,d.event,a.qevent_id,a.info1,a.info2,
               a.info3,a.info4,a.info5
            FROM  view_queue_stats a,tbl_qagent b, tbl_qname c, tbl_qevent d,
                tbl_server e
            WHERE  a.qagent_id=b.id
              AND  a.qname_id=c.id
              AND  a.qevent_id=d.id
              AND  a.server_id=e.id
              AND  DATE(a.queue_datetime) between '" . $start_date .
                                           "' AND '" . $end_date . "'
              AND  a.server_id IN ($server_name) 
      )as total
    GROUP BY  qevent_id,queue_id,server_id
    ORDER BY  length(server_name), server_name,queue_id,qevent_id. 

我认为通过分区视图进行搜索可以更快地执行查询。 为此,我应用了分区相关的参数来创建视图,但是没有成功。

以下是SHOW CREATE VIEW的输出view_queue_stats;

CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER 
       VIEW `view_queue_stats`
       AS    select  `tbl_queue_stats_0116`.`id` AS `id`,
       `tbl_queue_stats_0116`.`server_id` AS `server_id`,
       `tbl_queue_stats_0116`.`uniqueid` AS `uniqueid`,
       `tbl_queue_stats_0116`.`queue_datetime` AS `queue_datetime`,
       `tbl_queue_stats_0116`.`queue_timestamp` AS `queue_timestamp`,
       `tbl_queue_stats_0116`.`qname_id` AS `qname_id`,
       `tbl_queue_stats_0116`.`qagent_id` AS `qagent_id`,
       `tbl_queue_stats_0116`.`qevent_id` AS `qevent_id`,
       `tbl_queue_stats_0116`.`info1` AS `info1`,
       `tbl_queue_stats_0116`.`info2` AS `info2`,
       `tbl_queue_stats_0116`.`info3` AS `info3`,
       `tbl_queue_stats_0116`.`info4` AS `info4`,
       `tbl_queue_stats_0116`.`info5` AS `info5`
    from  `tbl_queue_stats_0116`
    union  all 
select  `tbl_queue_stats_0216`.`id` AS `id`,
       `tbl_queue_stats_0216`.`server_id` AS `server_id`,
       `tbl_queue_stats_0216`.`uniqueid` AS `uniqueid`,
       `tbl_queue_stats_0216`.`queue_datetime` AS `queue_datetime`,
       `tbl_queue_stats_0216`.`queue_timestamp` AS `queue_timestamp`,
       `tbl_queue_stats_0216`.`qname_id` AS `qname_id`,
       `tbl_queue_stats_0216`.`qagent_id` AS `qagent_id`,
       `tbl_queue_stats_0216`.`qevent_id` AS `qevent_id`,
       `tbl_queue_stats_0216`.`info1` AS `info1`,
       `tbl_queue_stats_0216`.`info2` AS `info2`,
       `tbl_queue_stats_0216`.`info3` AS `info3`,
       `tbl_queue_stats_0216`.`info4` AS `info4`,
       `tbl_queue_stats_0216`.`info5` AS `info5`
    from  `tbl_queue_stats_0216`
    union  all
    ...

| utf8                 | utf8_general_ci      |

那么,有什么方法可以分割视图吗?

您会有十亿个server_ids吗? 也许您可以使用较小的int,例如MEDIUMINT UNSIGNED ,它是3个字节(而不是4个字节),并且限制为16M。 与其他ID同上。 (更小->更多可缓存->更少的I / O->更快)

queue_timestamp是时间戳吗? 如果是这样,为什么要使用VARCHAR

cast(info2 AS SIGNED) -最好插入数据之前先清理数据,然后使用适当的数据类型( INT ?)。

重要:不要在函数中隐藏列( DATE(a.queue_datetime) ),它禁止使用索引; 见下文。

大多数字段真的是可选的吗? 如果不是,请说NOT NULL ,而不是NULL

重要:回到问题... UNION ALL 10个表的UNION ALL将类似于PARTITIONed表,在该表中不会发生“分区修剪”。 但是, UNION可能会更糟,因为它似乎会生成包含所有数据的临时表,然后开始过滤。 请为查询提供EXPLAIN SELECT ... (这应该确认或否认这种假设。这可能会带来很大的不同。)

重要提示: INDEX(server_id, queue_datetime)可能有助于提高性能。

因此,现在的问题是是否可能发生“修剪”。 可能的情况是query_datetime将结果限制为几个分区。 这些表是否基于query_datetime SELECTs通常只限于一个或两个表吗?

鉴于以上所述的正确答案以及建议的更改,那么从VIEW更改为VIEW将有很大帮助:

PARTITION BY RANGE(TO_DAYS(query_datetime)) ...

但是,事实证明,分区并不是真正必要的。 上面建议的INDEX (连同对WHERE的更改)在单个表上的效果一样好。

但是...还有更多问题。 您提到了一个SELECT 还有其他吗? 修正一个查询的查询/架构可能会或可能不会帮助其他查询。 您是否删除“旧”表/分区? 如果这样,分区可以很好地帮助您。

回答这些问题,然后我们可以进行中途更正。

检查下面给出的链接。这可能对您有帮助

http://dev.mysql.com/doc/refman/5.5/zh-CN/partitioning.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM