我有一个表:
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
我无法更改表或查询。但我知道,如果我将一个表拆分为两个分区——只选择可为null的值的查询将工作得更快。
我能用什么把戏来做这个?NULL和NOT NULL不是一个范围,我不能将其用作值列表。
PARTITION
可能没有帮助。
NULL
是INDEX中的一个单独值。可以将NULL看作是在所有其他值之前存储在INDEX中。因此,出于优化目的,IS NULL
和IS NOT NULL
可以被视为"范围"。
然而。。。如果超过20%(10%-30%,取决于月相)的表在所需范围内,优化器将决定进行完整的表扫描更快,而不是在INDEX和Data之间来回跳动。
回到我的可能。。。
- 如果一小部分行为NULL,那么索引就可以了;分区并没有多大帮助
- 如果中等数量的行有NULL,那么PARTITION可能会有明显的帮助
- 若大多数行都为NULL,则全表扫描几乎和扫描一个PARTITION的所有行一样好
注意:不能对多个列进行PARTITION。因此,如果您在PROPERTY_3139
上进行PARTITION,那么其余的属性将不走运。