小编fej*_*oco的帖子

Oracle 没有为长键使用唯一索引

我的测试数据库中有一个包含 250K 行的表。(生产中有几亿个,我们可以在那里观察到同样的问题。)该表有一个 nvarchar2(50) 字符串标识符,不为空,上面有一个唯一索引(不是 PK)。

标识符由第一部分组成,它在我的测试数据库中有 8 个不同的值(生产中大约有 1000 个),然后是一个 @ 符号,最后是一个 1 到 6 位长的数字。例如,可能有 5 万行以“ABCD_BGX1741F_2006_13_20110808.xml@”开头,后面跟着 5 万个不同的数字。

当我根据其标识符查询单行时,基数估计为1,成本很低,工作正常。当我在 IN 表达式或 OR 表达式中查询多个具有多个标识符的行时,对索引的估计是完全错误的,因此使用了全表扫描。如果我用提示强制索引,它会非常快,全表扫描实际上执行的速度要慢一个数量级(并且在生产中要慢得多)。所以这是一个优化器问题。

作为测试,我使用完全相同的 DDL 和完全相同的内容复制了表(在相同的模式+表空间中)。我在第一个表上重新创建了唯一索引以获得良好的度量,并在克隆表上创建了完全相同的索引。我做了一个DBMS_STATS.GATHER_SCHEMA_STATS('schemaname',estimate_percent=>100,cascade=>true);. 您甚至可以看到索引名称是连续的。所以现在这两个表唯一的区别是第一个是在很长一段时间内以随机顺序加载的,块分散在磁盘上(与其他几个大表一起在一个表空间中),第二个是作为一个批处理加载的插入-选择。除此之外,我想不出有什么不同。(自上次大删除以来,原始表已缩小,此后没有进行过一次删除。)

这里是sick和clone表的查询计划(黑色笔刷下的字符串全图相同,灰色笔刷下也是如此。):

查询计划

(在这个例子中,有1867行以刷黑的标识符开始。2行查询产生1867*2的基数,3行查询产生1867*3的基数,等等。不能巧合的是,Oracle 似乎并不关心标识符的结尾。)

什么可能导致这种行为?显然,在生产中重新创建表会非常昂贵。

USER_TABLES:http : //i.stack.imgur.com/nDWze.jpg USER_INDEXES:http : //i.stack.imgur.com/DG9um.jpg我只更改了架构和表空间名称。您可以看到表和索引名称与查询计划屏幕截图中的相同。

oracle optimization oracle-11g-r2

16
推荐指数
3
解决办法
2232
查看次数

MySQL时间戳时区处理

时间戳数据类型是表示即时值还是年月日时分秒值?一个瞬间就是一个瞬间,就像你开始阅读这篇文章的那一刻一样,它可以用许多不同的 ymdhm-s+timezone 值来描述。没有时区,这是模棱两可的,同一时刻对我来说可能是 17:25,对其他人来说可能是 13:25。

这就是我认为我得到的。该current_timestamp函数返回当前时区的当前时间,所以这是一个明确的时刻,真正的now。在表中,它存储为 UTC,因此使用这个假定的时区,它也应该是明确的。

现在这是我不明白的:这是utc_timestamp函数的存在。我将 acurrent_timestamp和 an存储utc_timestamp在同一列中,它们是不同的。这个函数甚至不应该存在,我不明白为什么它代表不同的时刻。

mysql timestamp timezone

8
推荐指数
2
解决办法
5万
查看次数