我有一个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分钟以上的时间。
1条答案
按热度按时间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...
--从长远来看,你可能会发现,这种混日子并不是做事的最佳方式。研究从每一列得到的值,看看它们是否值得标准化。看看什么长度更有意义:
如果distinct\ U values/total\ U rows>40%,则进行规格化(选择截止值)。
使用
longest
,加上软糖因子VARCHAR(...)
.使用
CHARACTER SET latin1
除非需要utf8。