mysql innodb select查询需要更多的时间来生成数据

csga3l58  于 2021-06-21  发布在  Mysql
关注(0)|答案(1)|浏览(270)

我有一个mysql innodb表,它使用每日表结构(一个单独的表来存储每日数据)。每个表由50列组成(由于此表用于存储每个表约有1600万行的cdr数据(与电信公司相关),因此无法规范化此表。
这是表架构:

CREATE TABLE IF NOT EXISTS <tableName_2018_07_08> ( 
 <col1> int(4) NOT NULL,
 <col2> timestamp NOT NULL,
 <col3> varchar(255) NOT NULL,
 <col4> int(4) NOT NULL,
 <col5> varchar(255) NOT NULL,
 <col6> varchar(255),
 <col7> varchar(255),
 <col8> varchar(255),
 <col9> varchar(255),
 <col10> varchar(255),
 <col11> varchar(255),
 <col12> varchar(255),
 <col13> varchar(255),
 <col14> varchar(255),
 <col15> varchar(255),
 <col16> varchar(255),
 <col17> varchar(255),
 <col18> varchar(255),
 <col19> varchar(255),
 <col20> varchar(255),
 <col21> varchar(255),
 <col22> varchar(255),
 <col23> varchar(255),
 <col24> varchar(255),
 <col25> varchar(255),
 <col26> varchar(255),
 <col27> varchar(255),
 <col28> varchar(255),
 <col29> varchar(255),
 <col30> varchar(255),
 <col31> varchar(255),
 <col32> varchar(255),
 <col33> varchar(255),
 <col34> varchar(255),
 <col35> varchar(255),
 <col36> varchar(255),
 <col37> varchar(255),
 <col38> varchar(255),
 <col39> varchar(255),
 <col40> varchar(255),
 <col41> varchar(255),
 <col42> varchar(255),
 <col43> varchar(255),
 <col44> varchar(255),
 <col45> varchar(255),
 <col46> varchar(255),
 <col47> varchar(255),
 <col48> varchar(255),
 <col49> varchar(255),
 <col50> varchar(255),
 PRIMARY KEY (<col1>, <col2>, <col3>, <col4>, <col5>)
) ROW_FORMAT=COMPACT ENGINE=InnoDB;

查询的where子句中使用了4个字段。

select 
    cast(<col1> as char),
    <col2>,
    <col3>,
    cast(<col4> as char),
    <col5>,
    <col6>,
    <col6>,
    <col7>,
    <col8>,
    <col9>,
    <col10>,
    <col11>,
    <col12>,
    <col13>,
    <col14>,
    <col15>,
    <col16>,
    <col16>,
    <col17>,
    <col18>,
    <col19>,
    <col20>,
    <col21>,
    <col22>,
    <col23>,
    <col24>,
    <col25>,
    <col26>,
    <col27>,
    <col28>,
    <col29>,
    <col30>,
    <col31>,
    <col32>,
    <col33>,
    <col34>,
    <col35>,
    <col36>,
    <col37>,
    <col38>,
    <col39>,
    <col40>
FROM 
    <tabele_2018_03_03> 
WHERE 
    col2 >= '2018-07-01 00:00:00' AND 
    col2 <= '2018-07-01 02:00:00' AND
    col3 = 'Test01' AND col4 = '11'

from time和to time是从前端发送的,另外还有三个过滤器,仅当这些过滤器是从前端发送时才添加。
此查询需要5分钟以上才能得到结果,这是一个问题。由于这只适用于一天,而且每当前端发送数据以获取数据达数天时,都需要10分钟以上的时间。

eit6fx6z

eit6fx6z1#

记忆?还是innodb?记忆是不稳定的;除了暂存,不要使用内存。
每天一张table——通常是个糟糕的设计。
“添加了更多过滤器”--让我们看看。您提供的任何查询解决方案可能对其他情况都没有帮助。
你想要2小时加1秒钟?检查范围测试。 cast(event as char) --不必要的;即使没有 cast .
没有以开头的索引 cdr_timestamp ,则该查询必须搜索整个表。添加索引可能没有帮助,因为查询可能正在查看表的2/24。
可以而且应该应用规范化。当然,数据是以字符串的形式出现的,但是在存储到'fact'表之前,应该转换更多的列。要多走一两步。看到了吗http://mysql.rjweb.org/doc.php/staging_table
这个链接提供了一些可以帮助你的技巧——你每秒插入大约200行,接近极限而不需要额外的步骤;这给了你一些步骤。它提供了一种2-sql规范化技术来非常有效地实现这一点。如果您的一些查询是“摘要报告”,那么它将深入研究如何使它们更快。等。
甚至盲目使用 (255) 因此,许多列都有很大的性能负担。
通过使用适当的数据类型,再加上规范化,将显著缩减磁盘占用空间,从而提供更高的性能。
5列用于 PRIMARY KEY --太多了。这是唯一标识行的列的最小组合吗?
你将如何处理百万行的输出??你不能用mysql来总结/压缩/任何数据吗?5分钟对于定位和铲取那么多数据来说并不是不合理的! reserved... --从长远来看,你可能会发现,这种混日子并不是做事的最佳方式。
研究从每一列得到的值,看看它们是否值得标准化。看看什么长度更有意义:

SELECT COUNT(*) AS total_rows,
       COUNT(DISTINCT vas_type) AS distinct values,
       MAX(CHAR_LENGTH(vas_type)) AS longest
    FROM tbl;

如果distinct\ U values/total\ U rows>40%,则进行规格化(选择截止值)。
使用 longest ,加上软糖因子 VARCHAR(...) .
使用 CHARACTER SET latin1 除非需要utf8。

相关问题