【问题标题】:mysql partition on categorical fields and timestamp column which is varchar分类字段和时间戳列上的mysql分区,它是varchar
【发布时间】:2019-06-19 03:43:50
【问题描述】:

目前我们有桌子:

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

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

运行任何查询都需要很长时间。

现在,我需要创建分区/索引。在现有表上尝试分区,它需要 forerver 才能运行。

对于上面列出的列(经常在 where 子句中使用)和日期列(YearMonthWeekDay)的最佳分区方法是什么? . 还有索引吗?

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

【问题讨论】:

  • 分区不会帮助你(它不是加速查询的工具),但索引会。您需要哪个索引取决于您的查询,因此请添加一两个具有代表性的查询(通常每个使用查询/用例都没有索引,因此从 1 开始)。相关方面:您的列是否与=in/a 范围一起使用?是否有特殊的数据分布? (也许(某些)列有 1% 的“1”和 99% 的“0”,而您通常只需要“1”行)。您的查询中(通常)包含哪些/多少列(例如,您通常可能包含一个日期范围,可能只是一天。)
  • 您可能会喜欢我的演示文稿How to Design Indexes, Reallyvideo
  • 您的表甚至没有主键!见stackoverflow.com/questions/840162/…

标签: mysql performance innodb partition database-partitioning


【解决方案1】:

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

建议你缩小数据——SMALLINT 占用 2 个字节; TINYINT UNSIGNED 占用 1 个字节,可以轻松保存您提到的所有这些小值。纬度/经度的小数点后 7 位为您提供低于 16 毫米或小于 1 英寸的精度。你需要那么精确吗?考虑 DECIMAL(8,6) 代表纬度和 (9,6) 代表经度;这将为每对节省 3 个字节。 (嗯……为什么有两对?)

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

这闻起来像数据仓库应用程序?如果是这样,也许构建和维护汇总表是要走的路。见http://mysql.rjweb.org/doc.php/summarytables。告诉我更多信息,我会帮助你的。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-10-19
    • 2019-12-28
    • 1970-01-01
    • 2017-06-03
    • 2023-02-19
    • 1970-01-01
    • 1970-01-01
    • 2020-03-24
    相关资源
    最近更新 更多