分类字段和时间戳列上的mysql分区为varchar

时间:2019-01-25 10:06:55

标签: mysql performance innodb partition database-partitioning

当前我们有一张桌子:

CREATE TABLE `T_TRANS` (
  `CASE_ID` varchar(20) DEFAULT NULL,
  `C_ID` varchar(20) DEFAULT NULL,
  `C_ST_IND` smallint(6) DEFAULT NULL,
  `D_DTTM` int(11) DEFAULT NULL,
  `E_ID` varchar(10) DEFAULT NULL,
  `E_LONG` decimal(11,7) DEFAULT NULL,
  `E_LAT` decimal(9,7) DEFAULT NULL,
  `EV_IND` smallint(6) DEFAULT NULL,
  `H_B_IND` smallint(6) DEFAULT NULL,
  `V_IND` varchar(15) DEFAULT NULL,
  `I_IND` smallint(6) DEFAULT NULL,
  `I_P_IND` smallint(6) DEFAULT NULL,
  `I_S_IND` smallint(6) DEFAULT NULL,
  `IS_D_IND` smallint(6) DEFAULT NULL,
  `IS_R_IND` smallint(6) DEFAULT NULL,
  `L_IND` smallint(6) DEFAULT NULL,
  `D_LONG` decimal(11,7) DEFAULT NULL,
  `D_LAT` decimal(9,7) DEFAULT NULL,
  `L_P_C_DTTM` int(11) DEFAULT NULL,
  `L_T_E_DTTM` int(11) DEFAULT NULL,
  `M_IND` varchar(20) DEFAULT NULL,
  `N_D_COUNTER` smallint(6) DEFAULT NULL,
  `O_ID` smallint(6) NOT NULL,
  `P_ID` varchar(50) DEFAULT NULL,
  `R_E_IND` smallint(6) DEFAULT NULL,
  `R_IND` smallint(6) DEFAULT NULL,
  `S_C_DTTM` varchar(20) DEFAULT NULL,
  `S_IND` smallint(6) DEFAULT NULL,
  `T_T_RED` varchar(20) DEFAULT NULL,
  `U_D` int(11) DEFAULT NULL,
  `V_D` int(11) DEFAULT NULL,
  `CRT_USR_NAM` varchar(45) DEFAULT NULL,
  `CRT_DTTM` varchar(45) DEFAULT NULL,
  `UPD_USR_NAM` varchar(45) DEFAULT NULL,
  `UPD_DTTM` varchar(45) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

我的where查询将在以下列中查询特定值或值的组合

C_ST_IND values range from (0,1,2,3,4,5,6,7,8,9,10,11,12)
E_IND values range from (0,1,2,3,4,5,6,7)
R_IND Values range from (0,1)
R_E_IND Values range from (0,1)
L_IND Values range from (0,1)
IS_D_IND Values range from (0,1)
I_S_IND Values range from (0,1)
I_P_IND Values range from (0,1)
I_IND Values range from (0,1)
S_IND Values range from (0,1,2,3)
H_B_IND Values range from (0,1)
O_ID Values range from (1,2,3,4,5,6)

我的日期列也以varchar格式-'2019-01-25 01:01:59' CRT_DTTMUPD_DTTM

平均-每日负载为

CRT_DTTM    Count
2019-01-20  656601
2019-01-21  686018
2019-01-22  668486
2019-01-23  680922
2019-01-24  693700

此表现在和当前正在生产中具有数百万条记录-没有任何分区和索引。

要花很多时间-运行任何查询。

现在,我需要创建分区/索引。尝试在现有表上进行分区,但要花很多时间才能运行。

对于CRT_DTTMUPD_DTTM,上面列出的列(通常在where子句中使用)和日期列(YearMonth)的最佳分区方法是什么, WeekDay分区。 还有索引吗?

此表将保存三年数据。目前,我们有3个月的数据。 如何将当前表移动到新的分区表。我是mysql的新手,任何信息都可以帮助减少生产查询的运行时间和报告生成。

1 个答案:

答案 0 :(得分:0)

PARTITIONs本质上不提供任何性能。让我们看一下查询,以便我们判断您是否有一种罕见的情况,例如清除“旧”数据。

建议您收缩数据-SMALLINT占用2个字节; TINYINT UNSIGNED占用1个字节,可以轻松保存您提到的所有小值。纬度/经度的7个小数位使您的精度低于16mm或小于一英寸。您需要那么多精度吗?对于纬度考虑DECIMAL(8,6),对于经度考虑(9,6);每对将节省3个字节。 (嗯。为什么会有两对?)

“长时间运行“任何”查询”?让我们看看其中的一些并进行优化。通常的问题是您需要触摸很多行。缩小行(如上所述)会有所帮助。但是最大的改进来自没有碰到太多行。

这闻起来像数据仓库应用程序吗?如果是这样,也许构建和维护摘要表是正确的方法。参见http://mysql.rjweb.org/doc.php/summarytables。向我显示更多信息,我会为您提供帮助。

您打算在3年后清除数据吗?如果是这样,我建议按月分区,并有38个分区。详细信息在这里:http://mysql.rjweb.org/doc.php/partitionmaint。这样,每晚68万行的DELETE变得更快了DROP PARTITION。 (与此同时,查询的性能可能没有任何好处。)

我的索引食谱:http://mysql.rjweb.org/doc.php/index_cookbook_mysql