mysql - 具有 70% 空值的列的索引 : Use null or empty value?

标签 mysql performance indexing null

我们目前正在优化一个 MySQL 表 (InnoDB),该表最终将拥有超过 1 亿行

在一列中,我们存储 IP 地址 (VARCHAR 45)。我们需要在该列上放置一个索引,因为我们必须能够检索每个特定 IP 地址的所有行。

但是,

70% 的所有行不会存储 IP 地址()。

我们的问题:我们是否应该将这些空值存储为 NULL,因此在此列上允许 NULL(将为每行添加 1 个字节)。 或者我们是否应该不允许 NULL 并将那些空值存储为作为''(空字符串)

什么最有利于性能?

我们将永远不必搜索空行 (= '') 或 null (IS NULL),只搜索特定的 IP 地址 (= '123.456.789.123')。

更新:确实有很多关于 SO 的问题可以解决类似的情况。但是,有些答案似乎是矛盾的,或者说“视情况而定”。我们将在此处运行一些测试并针对我们的特定场景发布我们的发现。

最佳答案

VARCHAR(39) 对于 IPv4(旧格式,没有更多可用值)和 IPv6 都足够了。

如果 70% 的值相同('' 或 NULL),优化器可能会出错。我建议您使用另一个带有 IP 和 ID 的表来加入您的原始表。通过在第二个表中没有“空”IP,优化器更有可能“做正确的事”。

这样,LEFT JOIN可以用来查看是否有IP。

IPv6 可以存储在 BINARY(16) 中以节省空间。

关于mysql - 具有 70% 空值的列的索引 : Use null or empty value?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34371494/

相关文章:

java - 使用版本作为部分主键,如何在给定 ID 的情况下获取实体的最新版本?

mysql - 如何将你自己的 mysql 连接传递给 Zend_DB?

lucene - 如何在 H2 数据库中无错误地使用设置 FULL-TEXT Lucene SEARCH?

visual-studio - 是否可以让 Visual Studio 索引源代码以改进字符串搜索?

java - 取自文本文件 : index out of range 的字符数组

mysql - Redis 用于语义 Web 应用程序 RDF quads 和 SparQL

mysql - SQL 从 2 个表更新 1 个表

performance - 为什么 Map 实现应该覆盖 foreach?

java - 禁用MongoDB中的主键索引并在批量插入后启用它?

Java:代码的性能和复杂性