【问题标题】:What does database query and insert speed depend on?数据库查询和插入速度取决于什么?
【发布时间】:2010-11-22 19:26:42
【问题描述】:

在我的工作中,我们有一个小型数据库(如 200 个表,总共可能有一百万行左右)。

我一直预计它会非常快,每秒插入数万次,并且在建立连接后查询需要几毫秒。

恰恰相反,我们遇到了一些性能问题,因此我们每秒只能获得几百个插入和查询,即使是最简单的查询也会永远占用。

我不确定这是标准行为/性能还是我们做错了什么。例如,1500 个查询意味着在一个键列上连接 4 个表大约需要 10 秒。使用简单的插入将 300K 的 xml 格式数据加载到数据库中需要 3 分钟,而不会违反任何约束。

数据库是 SQL Server 2005 并且具有丰富的关系依赖模型,这意味着对数据有很多关系和分类,以及对分类代码和其他一些东西的一整套检查约束。

这些时间对吗?如果没有,什么会影响性能? (所有查询都在索引列上完成)

【问题讨论】:

    标签: sql-server database sql-server-2005 performance insert


    【解决方案1】:

    粗略比较一下:TPC-C benchmark record for SQL Server 的交易量约为每分钟 120 万次,并且在过去 4 年左右的时间里一直如此(受 64 个 CPU 操作系统的限制)。这大约是 ~16k 每秒交易。这是在超高端机器、64 个 CPU、大量 RAM、每个 NUMA 节点的关联客户端和服务器短的剥离 I/O 系统上(每个主轴仅使用大约 1-2%)。请记住,这些是 TPC-C 事务,因此它们由多个操作组成(我认为平均每个操作 4-5 次读取和 1-2 次写入)。

    现在,您应该将这种顶级硬件缩减到您的实际部署,并了解在哪里设置您对整体 OLTP 事务处理的期望。

    对于数据上传当前的world record is about 1TB in 30 minutes(如果仍然是最新的...)。每秒数万次插入是相当雄心勃勃的,但如果在严格的硬件上正确完成,则可以实现。链接中的文章包含 ETL 高吞吐量的提示和技巧(例如,使用多个上传流并将它们关联到 NUMA 节点)。

    对于您的情况,我建议首先测量,以便您找出瓶颈,然后询问具体问题如何解决具体的瓶颈。 Waits and Queues whitepaper 是一个很好的起点。

    【讨论】:

    • 很好的答案。不过请注意,120 万 TPM = 20,000 TPS。
    【解决方案2】:

    索引是这里的一个主要因素,如果做得好,它们可以很好地加速 Select 语句,但请记住,索引会阻塞插入,服务器不仅会更新数据,还会更新索引。这里的诀窍是:

    1) 确定真正对速度至关重要的查询,这些查询应具有最佳索引。

    2) 填充因子在这里也很重要。这为索引页提供了空白空间以供以后填充。当索引页已满(插入了足够多的行)时,需要花费更多时间来创建新页。但是空页占用磁盘空间。

    我的诀窍是这样,对于每个应用程序,我将优先级设置如下:

    1) 读取速度(SELECT、一些 UPDATE、一些 DELETE)- 此优先级越高,我创建的索引越多
    2) 写入速度(插入、某些更新、某些删除)- 此优先级越高,我创建的索引越少
    3) 磁盘空间效率——这个优先级越高,我的填充因子就越高

    请注意,此知识通常适用于 SQL Server,您的里程可能因不同的 DBMS 而异。

    SQL 语句评估在这里也可以提供帮助,但这需要真正的专业人士,仔细的 WHERE 和 JOIN 分析可以帮助确定瓶颈以及查询遇到的问题。打开 SHOWPLAN 并查询计划,评估您所看到的并相应地计划。

    还请查看 SQL Server 2008,索引连接!

    【讨论】:

      【解决方案3】:

      “丰富的关系依赖”模型不利于快速插入速度。必须检查每条插入记录的每个约束(主键、值检查,尤其是外键)。这比“简单插入”要多得多。

      您的插入没有违反约束并没有什么问题,时间可能全部用于检查您的外键。除非你也有触发器,因为它们更糟。

      当然,唯一错误的可能是您的 Insert 表是另一个表的父 FK 的“必备子”FK 关系,而忘记为子 FK 端添加索引关于 FK 关系(这不是自动的,经常被遗忘)。当然,那只是希望运气好。:-)

      【讨论】:

        【解决方案4】:

        约束会增加一点性能损失。它还必须为每个插入更新索引。而且,如果您不将多个插入放入单个事务中,数据库服务器必须将每个插入作为一个新的独立事务执行,从而进一步减慢它。

        150 次查询/秒加入 4 个表听起来很正常,但我对您的数据了解不多。

        【讨论】:

          【解决方案5】:

          “我一直预计它会非常快,每秒插入数万次,并且一旦建立连接,查询需要几毫秒。”

          (a) 数据库性能 99% 取决于物理 I/O 的数量(除非您在一些使用内存数据库的小型站点中,它可以无害地将所有物理 I/O 推迟到一天之后已经完成了)。 (b) 数据库 I/O 不仅涉及到数据文件的实际物理 I/O,还涉及持久化日志/日志/...的物理 I/O(并且日志记录通常甚至在双模式下完成(即两次)因为说大约二十年左右)。 (c)“插入量”以何种方式对应于“物理I/O量”,完全取决于数据库设计者有多少选项可用于优化物理设计。关于这一点,一般只能说一件事:SQL 系统大多失败(提供将“数万个插入”转换为“数百个”物理 I/O 所需的选项)。这意味着“数万次插入”通常也意味着“数以千计的物理 I/O”,这通常意味着“数十秒”。

          也就是说,您的消息似乎表达了一种期望,即“插入速度非常快(“每秒数万次”),而“查询速度较慢”(“每次查询毫秒数”,意味着“每次查询少于 1000 个第二”)。这种期望是荒谬的。

          【讨论】:

          • 预期是由于我使用的查询比插入的查询要复杂得多。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-09-11
          • 2017-07-06
          • 1970-01-01
          • 1970-01-01
          • 2014-08-10
          相关资源
          最近更新 更多