在什么条件下,SELECT by PRIMARY KEY会变慢?

时间:2010-07-28 16:36:01

标签: sql database jpa performance eclipselink

在相当典型的EclipseLink / JPA应用程序中查找一些数据库性能问题。

我看到频繁的查询需要25-100毫秒。这些是简单查询,只是从表中选择其主键等于值的所有列。他们不应该慢。

我正在查看postgres日志中的查询时间,使用log_min_duration_statement,这样可以消除任何网络或应用程序开销。

此查询速度不慢,但经常使用。

为什么主键选择*会变慢? 这是特定于postgres还是一般数据库问题? 我怎样才能加快速度呢?一般来说?对于postgres?

来自pg日志的示例查询:

2010-07-28 08:19:08 PDT - LOG:  duration: 61.405 ms  statement: EXECUTE <unnamed>  [PREPARE:  SELECT coded_ele
ment_key, code_system, code_system_label, description, label, code, concept_key, alternate_code_key FROM coded
_element WHERE (coded_element_key = $1)]

表有大约350万行。

我还在此查询上运行EXPLAIN和EXPLAIN ANALYZE,它只进行索引扫描。

5 个答案:

答案 0 :(得分:4)

选择*会使您的数据库更加困难,并且作为一般规则,这是一种不好的做法。 stackoverflow上有很多问题/答案在讨论这个问题。

你试过用字段名替换*吗?

答案 1 :(得分:2)

你能获得某种锁定争用吗?执行这些查询时您采取了哪种锁?

答案 2 :(得分:2)

好吧,我对postgres SQL了解不多,所以我会给你一个可能适用的MS SQL Server提示。

MS SQL Server具有“群集索引”的概念,它是磁盘上数据的物理布局。在字段上使用是很好的,你将寻找值之间的范围(主要是日期字段)。如果你正在寻找一个确切的值(比如主键查找),那就没什么用了。但是,有时主键索引无意中被设置为聚簇索引。这使索引查找到表扫描。

答案 3 :(得分:1)

select *几乎总是一个非常糟糕的主意。

  1. 如果字段的顺序发生变化,则会破坏您的代码。 根据评论,鉴于您正在使用的抽象库,这并不重要。
  2. 您可能从表中返回的数据超出了您的实际需求。选择所需的特定字段可以节省传输时间。
  3. 25ms是关于你将在几乎任何类型的SQL查询上看到的下限 - 这只是两次磁盘访问!您可能希望研究减少查询运行次数的方法,而不是尝试优化查询。

答案 4 :(得分:1)

该行异常大还是包含BLOB和大二进制字段?

这是直接通过控制台还是通过某些数据访问API(如jdbc或ADO.NET)运行此查询?您提到的JPA看起来像数据访问API。对于简短查询,数据访问API占执行时间的百分比更大 - 创建命令,创建用于保存行和单元格的对象等。