4.3.1 分析Delphi查寻结果数据集方法的行为
为什么当使用Locate、Lookup等的方法查寻数据时,如果数据表包含的数据愈多,查寻的速度就愈缓慢呢?当然,从理论上说,当数据愈多时查寻的速度本来就应该比较缓慢,因为要查寻的数据比较多嘛。但是如果查寻的时间是以数倍的时间成长,那么就意味着有一些事情不对劲了。
要知道Locate、Lookup如何在大量数据的数据表中查寻数据,只需要打开TSQLMonitor即可了解,下面的执行状态便是使用Locate在一个数据表中查寻数据的情形:
INTERBASE - isc_dsql_allocate_statement
INTERBASE - isc_start_transaction
Select * from PERFTEST order by ID
INTERBASE - isc_dsql_prepare
INTERBASE - isc_dsql_describe_bind
INTERBASE - isc_dsql_execute
INTERBASE - isc_dsql_fetch
INTERBASE - isc_dsql_allocate_statement
SELECT 0, '', '', A.RDB$RELATION_NAME, A.RDB$INDEX_NAME, B.RDB$FIELD_NAME, B.RDB$FIELD_POSITION, '', 0, A.RDB$INDEX_TYPE, '', A.RDB$UNIQUE_FLAG, C.RDB$CONSTRAINT_NAME, C.RDB$CONSTRAINT_TYPE FROM RDB$INDICES A, RDB$INDEX_SEGMENTS B FULL OUTER JOIN RDB$RELATION_CONSTRAINTS C ON A.RDB$RELATION_NAME = C.RDB$RELATION_NAME AND C.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY' WHERE (A.RDB$SYSTEM_FLAG <> 1 OR A.RDB$SYSTEM_FLAG IS NULL) AND (A.RDB$INDEX_NAME = B.RDB$INDEX_NAME) AND (A.RDB$RELATION_NAME = UPPER('PERFTEST')) ORDER BY RDB$INDEX_NAME
INTERBASE - isc_dsql_prepare
INTERBASE - isc_dsql_describe_bind
INTERBASE - isc_dsql_execute
INTERBASE - isc_dsql_fetch
INTERBASE - isc_dsql_fetch
INTERBASE - isc_commit_retaining
INTERBASE - isc_dsql_free_statement
INTERBASE - isc_dsql_free_statement
INTERBASE - isc_dsql_fetch
INTERBASE - isc_dsql_fetch
INTERBASE - isc_dsql_fetch
INTERBASE - isc_dsql_fetch
INTERBASE - isc_dsql_fetch
INTERBASE - isc_dsql_fetch
INTERBASE - isc_dsql_fetch
…
数千次的fetch
从上面的列表中我们可以分析出当程序使用Locate、Lookup等的方法在结果数据集中查寻数据时,DataSnap会先让dbExpress从数据来源取得所有的数据之后,再于结果数据集中查寻数据,即使是要查寻的数据已经存在于结果数据集中,DataSnap仍然会先取得所有的数据。
由于dbExpress驱动程序版本不断地在更新,因此读者使用TSQLMonitor追踪的结果有可能和本书列出的有所不同。
这种执行行为模式虽然简单,但是对于拥有大量数据的数据表而言,却非常没有效率。例如如果数据表拥有十万笔数据,那么DataSnap会把十万笔数据完全取到客户端,再进行查寻。这样不但会花上许多的时间,而且很有可能会把客户端的应用程序当掉,因为这需要客户端大量的内存。
因此,要有效率地在结果数据集中查寻数据,就必须避免这种情形发生,让DataSnap/dbExpress不要把大量的数据下载到客户端。在稍后的章节中会以一个实际的范例来说明如何一步一步地改善查寻数据的效率。但是稍后讨论的技巧并不是要应用在所有的情形中,开发人员应该根据数据表中数据的数量来决定。下面就分别讨论。






