MySQL的空值分区

时间:2015-04-01 12:55:11

标签: mysql database query-optimization partitioning database-partitioning

我有一张桌子:

CREATE TABLE `NewTable` (
    `IBLOCK_ELEMENT_ID`  int(11) NOT NULL ,
    `PROPERTY_1836`  int(11) NULL DEFAULT NULL ,
    `DESCRIPTION_1836`  varchar(255) CHARACTER SET cp1251 COLLATE cp1251_general_ci NULL DEFAULT NULL ,
    `PROPERTY_1837`  int(11) NULL DEFAULT 0 ,
    `DESCRIPTION_1837`  varchar(255) CHARACTER SET cp1251 COLLATE cp1251_general_ci NULL DEFAULT NULL ,
    `PROPERTY_1838`  decimal(18,4) NULL DEFAULT NULL ,
    `DESCRIPTION_1838`  varchar(255) CHARACTER SET cp1251 COLLATE cp1251_general_ci NULL DEFAULT NULL ,
    `PROPERTY_3139`  int(11) NULL DEFAULT 0 ,
    `DESCRIPTION_3139`  varchar(255) CHARACTER SET cp1251 COLLATE cp1251_general_ci NULL DEFAULT NULL ,
    `PROPERTY_3173`  decimal(18,4) NULL DEFAULT NULL ,
    `DESCRIPTION_3173`  varchar(255) CHARACTER SET cp1251 COLLATE cp1251_general_ci NULL DEFAULT NULL ,
    PRIMARY KEY (`IBLOCK_ELEMENT_ID`),
    INDEX `ix_perf_b_iblock_element_pr_1` (`PROPERTY_1837`) USING BTREE ,
    INDEX `ix_perf_b_iblock_element_pr_2` (`PROPERTY_1836`) USING BTREE ,
    INDEX `ix_perf_b_iblock_element_pr_3` (`PROPERTY_3139`) USING BTREE 
)
ENGINE=InnoDB
DEFAULT CHARACTER SET=cp1251 COLLATE=cp1251_general_ci
ROW_FORMAT=COMPACT;

带条件的查询:

WHERE PROPERTY_3139 IS NULL

我无法更改表格或查询。但我知道,如果我将表拆分为2个分区 - 只选择可空值的查询将会更快地运行。

我可以使用什么样的技巧来做到这一点? NULL和NOT NULL不是范围,我不能将其用作值列表。

1 个答案:

答案 0 :(得分:1)

PARTITION 可能没有帮助。

NULL是INDEX中的单独值。可以将NULL视为在所有其他值之前存储在INDEX中。因此,IS NULLIS NOT NULL可被视为'范围'用于优化目的。

然而......如果表的超过20%(10%-30%,具体取决于月相)在所需范围内,优化器将决定进行全表扫描更快而不是在INDEX和数据之间来回反弹。

回到我的可能 ...

  • 如果少量行有NULL,那么索引会很好; PARTITIONing没有多大帮助。
  • 如果中等行数为NULL,则PARTITIONing可能会有明显的帮助。
  • 如果大多数行都为NULL,则全表扫描几乎与扫描所有PARTITION一样好。

注意:您不能在多个列上进行PARTITION。因此,如果您在PROPERTY_3139上进行PARTITION,其他属性将会运气不佳。