Sql server 如何从SQL server 2012查询链接的DB2服务器时更快地统计记录

Sql server 如何从SQL server 2012查询链接的DB2服务器时更快地统计记录,sql-server,count,db2,Sql Server,Count,Db2,我的设置是-在我的机器上有一个带有3个链接的DB2服务器的sqlserver2012实例。大多数操作都需要花费大量时间,因此我希望尽可能多地优化每个查询。从现在起,我一直在使用COUNT(*),我知道这是一种相对较慢的方法,但现在返回结果需要19秒,所以这是不可接受的 我读过关于这个主题的文章,我发现主要关注的是结果的准确性,但由于我主要使用这些数据来执行分页,所以获得绝对准确的数字并不重要,我很乐意使用更快且不是100%准确的数字 我尝试了以下查询: select * from openqu

我的设置是-在我的机器上有一个带有3个链接的
DB2
服务器的
sqlserver2012
实例。大多数操作都需要花费大量时间,因此我希望尽可能多地优化每个查询。从现在起,我一直在使用
COUNT(*)
,我知道这是一种相对较慢的方法,但现在返回结果需要19秒,所以这是不可接受的

我读过关于这个主题的文章,我发现主要关注的是结果的准确性,但由于我主要使用这些数据来执行分页,所以获得绝对准确的数字并不重要,我很乐意使用更快且不是100%准确的数字

我尝试了以下查询:

select *
 from openquery(MyLinkedServer,
 '
  select sum (spart.rows)
  from sys.partitions spart
  where spart.object_id = object_id(''MyTable'')
  and spart.index_id < 2

 '
)
昨天花了19秒执行,今天我得到:

**SQL0666 - SQL query exceeds specified time limit or storage limit.**

我不知道发生了什么。我取消勾选了“允许查询超时”,但没有任何效果。

SQL0204N错误指的是未定义的名称。如果没有关于数据的更多信息,很难对确切的错误进行故障排除,但是有(找到与您的DB2版本相同的文档,因为存在差异)

至于
count(*)
,如果您需要计算行数,这与您可以用于该任务的任何方法一样有效。回避它不会有任何好处

如果您的查询耗时19秒,与上面显示的查询类似,则可能会很慢,因为您正在为每一行调用函数
object\u id()
。您可以通过指定函数是确定性的(为每个输入返回相同的输出)来对此进行优化。理论上,这将阻止DB2每次调用该函数

或者您可以重写查询以从
where
子句中删除函数调用。

从mytable中选择COUNT(*)在IBM i上是一个非常快速的操作。我有一张几乎有1700万行的桌子,上面的内容马上就回来了。我有一个更小更旧的盒子

只有在添加
WHERE
子句时,事情才会变得缓慢。与任何数据库上的任何其他操作一样,索引起着重要作用。实际上,IBMi在计算行数方面比其他大多数数据库都有优势。IBMi像任何其他数据库一样支持标准位图索引;但它也支持另一种称为编码向量索引(EVI)的索引类型。我不会详细介绍所有的细节,但是为了计算行数和EVI索引,它非常有用,因为每个键的行数都是索引本身的一部分。正如您可以想象的那样,这使得使用匹配键计算行的速度非常快

返回您的代码
[IBM][iSeries Access ODBC驱动程序][DB2 UDB]SQL0204-未找到SYS type*文件中的分区。

错误很明显。IBMi中没有SYS.PARTITIONS表。SYS.PARTITIONS既不是ANSI/ISO标准目录,也不是JDBC/ODBC标准目录;它是特定于MS SQL Server的

最新版本(7.2)可用的DB2forIBMi目录视图如下所示:

对于v5r4(5.4),请查看此处:

QSYS2中的SYSPARTITIONSTAT似乎是IBMi与MS SQL的SYS.PARTITIONS最接近的。但是,没有对象ID或索引ID列

如果你想要的只是行数,我只需要使用

SELECT COUNT(*)
FROM MYLIB.MYTABLE
因为它应该立即返回。通过链接服务器,您将有一些开销。要查看查询量,可以使用IBM工具(如(绿色屏幕)STRSQL或(Java)iNav的RunSQL脚本直接运行查询。松鼠也可以使用

如果确实要查询元数据,则:

SELECT NUMBER_ROWS
FROM QSYS2.SYSPARTITIONSTAT
WHERE TABLE_NAME = 'MYTABLE'
  AND TABLE_SCHEMA = 'MYLIB'
*注意,还有一个SYSTEM_TABLE_NAME和SYSTEM_TABLE_SCHEMA列,其中包含10个字符的SYSTEM TABLE&SCHEMA名称

但如果它表现得更快,我会感到惊讶。在我的系统上,在1700万行的表上,
selectcount(*)
花费了39毫秒,查询SYSPARTITIONSTAT花费了135毫秒

查看您添加的
COUNT(*)
code…
像“%Peter%”这样的
将损害性能,因为无法使用索引查找。充其量,您看到的是完整的索引扫描。确保你有一个系统可以使用的索引。我将尝试3种不同的方案,看看系统使用哪种索引。(使用iSeries Navigator的运行SQL脚本中的运行和解释)

  • 每列上的单独(位图)索引
  • 每列上单独的EVI索引
  • 所有三列上都有1个组合(第一个中间最后一个)(位图)索引
你也试过这种格式吗

WHERE P.FirstName  like ''%Peter%''
   OR P.MiddleName like ''%Peter%''
   OR P.LastName   like ''%Peter%''
这应该允许数据库搜索更少的工作,特别是当大多数匹配来自
p.FirstName
,并且它不必使用任何临时存储来连接数据时。注意:我还去掉了
TRIM()
这两种情况下都不需要它。我怀疑这会让你付出一些代价。它可能有帮助,但在这种情况下,
TRIMR()
会更好。最好的解决方案是首先使用可变长度的列

您的原始格式(带或不带
TRIM()
可能更有利于上面的第三个索引选项(1个组合索引)。而其他两个索引选项更有利于前两个选项

创建上面提到的所有7个索引,然后使用Run&Explain尝试各种场景,看看每个场景都发生了什么

在两次尝试之间, -断开并重新连接系统
-使用SETOBJACC OBJ(个人)OBJTYPE(*文件)池(*清除)


这将使缓存保持在最低限度,并且比较结果相等。

感谢您的asnwer。我的版本是
V5R4
,据我所知,它非常旧,在出现时仍然没有实现一些
SQL SERVER
函数,这让我想到我是否真的使用这种方法进行计数。至于
WHERE P.FirstName  like ''%Peter%''
   OR P.MiddleName like ''%Peter%''
   OR P.LastName   like ''%Peter%''