按日期对大表进行分区

问题描述 投票:1回答:1

我已经在我的应用中实现了自定义网址缩短器,为此我有一张表。表结构如下:

CREATE TABLE `urls` (
  `id` int(11) NOT NULL,
  `url_id` varchar(10) DEFAULT NULL,
  `long_url` varchar(255) DEFAULT NULL,
  `clicked` mediumint(5) NOT NULL DEFAULT 0,
  `user_id` varchar(7) DEFAULT NULL,
  `type` varchar(15) DEFAULT NULL,
  `ad_id` int(11) DEFAULT NULL,
  `campaign` int(11) DEFAULT,
  `increment` tinyint(1) NOT NULL DEFAULT 0,
  `date` date DEFAULT NULL,
  `del` enum('1','0') NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT

ALTER TABLE `urls`
  ADD PRIMARY KEY (`id`),
  ADD KEY `url_id` (`url_id`),
  ADD KEY `type` (`type`),
  ADD KEY `campaign` (`campaign`),
  ADD KEY `ad_id` (`ad_id`),
  ADD KEY `date` (`date`),
  ADD KEY `user_id` (`user_id`);

该表现在有20.000.000条记录,目前每天增长30万至40万条记录。

url_id列是唯一的varchar(10),URL看起来像这样:http://example.com/asdfghjklu

现在我已按HASH(id)将此表划分为10个分区:

PARTITION BY HASH (`id`)
PARTITIONS 10;

[当我尝试生成报告并将该表加入其他人的查询时,查询的速度变得非常缓慢,因此,即使无法获得1周的报告,也是如此。

[当我尝试在此表中进行大查询时,我几乎用日期过滤所有查询,我认为如果按date列对该表进行分区会更好。这是个好主意吗?

如我所读,如果我想按日期对表进行分区,则需要在复合主键中添加日期:PRIMARY KEY(id, date)

您对此有何看法?如何提高查询性能?

mysql sql database relational-database partition
1个回答
0
投票

我建议使用使用日期或月份或年份的哈希分区

CREATE TABLE `urls` (
  `id` int(11) NOT NULL,
  `url_id` varchar(10) DEFAULT NULL,
  `long_url` varchar(255) DEFAULT NULL,
  `clicked` mediumint(5) NOT NULL DEFAULT 0,
  `user_id` varchar(7) DEFAULT NULL,
  `type` varchar(15) DEFAULT NULL,
  `ad_id` int(11) DEFAULT NULL,
  `campaign` int(11) DEFAULT,
  `increment` tinyint(1) NOT NULL DEFAULT 0,
  `date` date DEFAULT NULL,
  `del` enum('1','0') NOT NULL DEFAULT '0',
    PartitionsID int(4) unsigned NOT NULL,
   KEY PartitionsID (PartitionsID)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
PARTITION BY HASH (PartitionsID)
PARTITIONS 366;

在分区ID中,您只需要插入TO_DAYS(date),因此整天您只有一个值。SOURCE

这将使每天的分区变得容易,或者也可以根据数据大小按月进行分区。

用于选择您可以使用以下查询作为示例

SELECT *    
            FROM TT ACT
            WHERE ACT.CustomerID = vCustomerID 
              AND ACT.TransactionTime BETWEEN vInvoiceEndDate AND vPaymentDueDate 
              AND ACT.TrxnInfoTypeID IN (19, 23) 
              AND ACT.PaymentType = '1'
    AND ACT.PartitionsID BETWEEN TO_DAYS(vInvoiceEndDate) AND TO_DAYS(vPaymentDueDate);
© www.soinside.com 2019 - 2024. All rights reserved.