为了存储 128 位 UUID,有多种存储选项:
从索引的角度来看,哪些是最有效的?如果数据库不支持专用的 uuid 类型,那么 1、2、3 中的哪一个是最佳选择?
在更新一行时,许多 ORM 工具发出一个 UPDATE 语句,设置与该特定实体关联的每一列。
优点是您可以轻松地批量更新语句,因为UPDATE无论您更改什么实体属性,语句都是相同的。此外,您甚至还可以使用服务器端和客户端语句缓存。
所以,如果我加载一个实体并且只设置一个属性:
Post post = entityManager.find(Post.class, 1L);
post.setScore(12);
Run Code Online (Sandbox Code Playgroud)
所有列都将被更改:
UPDATE post
SET score = 12,
title = 'High-Performance Java Persistence'
WHERE id = 1
Run Code Online (Sandbox Code Playgroud)
现在,假设我们也有一个关于该title属性的索引,数据库难道不应该意识到该值无论如何都没有改变吗?
在这篇文章中,Markus Winand 说:
所有列的更新显示了我们在前几节中已经观察到的相同模式:响应时间随着索引的增加而增加。
我想知道为什么会有这种开销,因为数据库将关联的数据页从磁盘加载到内存中,因此它可以确定是否需要更改列值。
即使对于索引,它也不会重新平衡任何内容,因为对于未更改的列,索引值不会更改,但它们已包含在 UPDATE 中。
是不是和冗余不变列关联的B+树索引也需要导航,数据库才意识到叶子值还是一样的?
当然,一些 ORM 工具允许您只更新更改的属性:
UPDATE post
SET score = 12,
WHERE id = 1
Run Code Online (Sandbox Code Playgroud)
但是,当不同行的不同属性更改时,这种类型的 UPDATE 可能并不总是从批量更新或语句缓存中受益。
我在与 Lukas Eder的Twitter 对话中偶然发现了这个问题。
尽管正确的行为是在最外层查询上应用 ORDER BY 子句,因为在这里,我们没有在最外层查询中使用 DISTINCT、GROUP BY、JOIN 或任何其他 WHERE 子句,为什么 RDBMS 不只是通过传入的数据是按内部查询排序的吗?
SELECT *
FROM (
SELECT * FROM table ORDER BY time DESC
) AS t
Run Code Online (Sandbox Code Playgroud)
在 PostgreSQL 上运行此示例时,至少,您会为内部查询和此派生表示例获得相同的执行计划,以及相同的结果集。
因此,我假设 Planner 将简单地丢弃最外层的查询,因为它是多余的,或者只是通过内部表的结果。
有没有人认为情况可能并非如此?
在测试 Oracle XE 连接建立机制时,我遇到了以下问题。虽然连接在每次迭代时关闭,但在 50-100 个连接后 Oracle 开始间歇性地抛出以下异常:
java.sql.SQLException: Listener refused the connection with the following error:
ORA-12516, TNS:listener could not find available handler with matching protocol stack
at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:489) ~[ojdbc6-11.2.0.4.jar:11.2.0.4.0]
at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:553) ~[ojdbc6-11.2.0.4.jar:11.2.0.4.0]
at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:254) ~[ojdbc6-11.2.0.4.jar:11.2.0.4.0]
at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:32) ~[ojdbc6-11.2.0.4.jar:11.2.0.4.0]
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:528) ~[ojdbc6-11.2.0.4.jar:11.2.0.4.0]
at oracle.jdbc.pool.OracleDataSource.getPhysicalConnection(OracleDataSource.java:280) ~[ojdbc6-11.2.0.4.jar:11.2.0.4.0]
at oracle.jdbc.pool.OracleDataSource.getConnection(OracleDataSource.java:207) ~[ojdbc6-11.2.0.4.jar:11.2.0.4.0]
at oracle.jdbc.pool.OracleDataSource.getConnection(OracleDataSource.java:157) ~[ojdbc6-11.2.0.4.jar:11.2.0.4.0]
at com.vladmihalcea.book.high_performance_java_persistence.jdbc.connection.OracleConnectionCallTest.test(OracleConnectionCallTest.java:57) [test-classes/:na]
Run Code Online (Sandbox Code Playgroud)
测试可以在 GitHub 上找到:
for (int i = 0; i < callCount; i++) {
try {
long startNanos = System.nanoTime();
try (Connection connection = …Run Code Online (Sandbox Code Playgroud) PostgreSQL 支持使用如下查询检索当前正在运行的事务 ID:
select txid_current();
Run Code Online (Sandbox Code Playgroud)
MySQL 有没有这样的等价物?
mysql ×3
oracle ×3
postgresql ×3
index ×2
connections ×1
oracle-xe ×1
order-by ×1
orm ×1
performance ×1
process ×1
sql-server ×1
transaction ×1
update ×1