如果您不关心日志记录表的一致性,为什么不从单独的线程执行所有日志记录。
我可能不会在记录之前等待事务完成,因为日志对于诊断长期运行的事务至关重要。此外,这使您能够查看回滚的事务所做的所有工作。
在日志线程中获取堆栈跟踪和所有日志数据, 当有新的日志消息时将其放入队列中,在单个事务中将它们刷新到数据库。
最小化锁定的步骤:
- (KEY) 在主线程/连接/事务之外执行所有附加到日志表。
- 确保您的日志记录表具有单调增加的聚集索引(例如 int identity ),每次附加日志消息时该索引都会增加。这样可以确保插入的页面通常在内存中,并避免堆表对性能的影响。
- 在事务中对日志执行多个附加(事务中的 10 次插入比事务中的 10 次插入快,并且通常获取/释放更少的锁)
- Give it a break. Only perform logging to your db every N milliseconds. Batch up bits of works.
- If you need to report on stuff historically, you can consider partitioning your logging table. Example: You could create a new logging table every month, and at the same time have a log VIEW that is a UNION ALL of all the older logging tables. Perform the reporting against the most appropriate source.
You will get better performance by flushing multiple logging messages in a single (smallish) transaction, and have the advantage that if 10 threads are doing work and logging stuff, only a single thread is flushing stuff to the logging table. This pipelining actually makes stuff scale better.