【问题标题】:Counting Number Of Specific Record In Database统计数据库中特定记录的数量
【发布时间】:2016-02-28 17:32:14
【问题描述】:

我有一个应用程序需要知道数据库表中一些记录的最新数量,该解决方案应该适用,而无需更改数据库代码或向其添加触发器或函数,因此我需要一个独立于数据库供应商的解决方案。 我的程序是用 java 编写的,但数据库可能是(SQLite、MySQL、PostgreSQL 或 MSSQL),现在我正在这样做: 在设置为守护进程的单独线程中,我的应用程序通过 JDBC 向数据库发送一个简单的命令,以了解最新的记录数量:

while(true){
          SELECT COUNT(*) FROM Mytable WHERE exited='1'
}

这种编码会导致 DATABASE 锁定,减慢整个系统并生成巨大的数据库日志,最终导致整个系统崩溃! 我怎样才能以正确的方式始终拥有某些记录的最新数量或仅在数量发生变化时才计数?

【问题讨论】:

  • 我不明白为什么这样的语句会导致巨大的数据库日志,但您可以通过在exited上创建索引来改进系统
  • 在繁忙的循环中查询数据库是一个糟糕的主意。您能否更改代码以便仅按需查询计数?您在应用程序中的什么地方使用计数?

标签: java database jdbc


【解决方案1】:

SELECT 语句本身不应具有您所描述的行为。例如,SELECT 不会记录任何内容。现在,有可能并发的insert/update/delete 语句正在运行,这些会导致问题,因为SELECT 锁定了表。

你可以做两件事:

  1. 确保比较属于同一类型。因此,如果exited 是数字,请不要使用单引号(混合类型可能会混淆某些数据库)。
  2. (exited) 上创建索引。在基本上所有数据库中,这是一个命令:create index idx_mytable_exited on mytable(exited)

如果锁定和并发事务是一个问题,那么您将需要做更多特定于数据库的事情,以避免该问题。

【讨论】:

  • 另外,如果后台线程不是自动提交,保持连接打开,并且从不提交,打开的事务可能会导致问题。运行SELECT 后调用conn.commit() 关闭事务。在没有执行更新时调用 commit() 可能看起来违反直觉,但这是必要的。
  • @Gordon Linoff 线程一直在不停地做select语句,你说这种方法安全吗?!
【解决方案2】:

正如其他人所说,确保 exited 已编入索引。

此外,您可以在查询中设置事务隔离以进行“脏读”;这向数据库服务器表明您不需要等待其他进程的事务提交,而是希望读取那些其他进程正在更新的行上的 exited 的当前值。

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED 是使用“脏读”的标准语法。

【讨论】:

    猜你喜欢
    • 2023-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-24
    • 2013-06-18
    • 1970-01-01
    • 2013-05-16
    • 2016-08-21
    相关资源
    最近更新 更多