逻辑列的查询

在学习本节内容之前,请先打开CaseStudy目录下的文件:逻辑列的查询.Table

本节内容有两个表,表A的结构为:

表B的结构为:

希望在表B统计出客户的付款和欠款总额,通常大家会写出这样的代码:

Dim nms As List(of String) = DataTables("表A").GetValues("客户")
DataTables(
"表B").StopRedraw()
For Each
nm As String In nms
    Dim
dr As DataRow = DataTables("表B").AddNew()
   
dr("客户") = nm
    dr
("付款合计") = DataTables("表A").Compute("Sum(金额)", "客户 = '" & nm & "' And 已付款 = True")
   
dr("欠款合计") = DataTables("表A").Compute("Sum(金额)", "客户 = '" & nm & "' And 已付款 = False")
Next
DataTables(
"表B").ResumeRedraw()

在表A为5000行,客户数为1000的时候,执行上述代码所花费的时间为26秒,效率不太理想。

经过分析,我怀疑是因为逻辑值的比较导致运行效率偏低,为了验证这个想法,我将已付款列改为字符型,用"Y"表示已经付款,"N"表示未付款,将代码改为:

Dim nms As List(of String) = DataTables("表A").GetValues("客户")
DataTables(
"表B").StopRedraw()
For Each
nm As String In nms
    Dim
dr As DataRow = DataTables("表B").AddNew()
    dr
("客户") =
nm
   
dr("付款合计") = DataTables("表A").Compute("Sum(金额)", "客户 = '" & nm & "' And 已付款 = 'Y'")
    dr
("欠款合计") = DataTables("表A").Compute("Sum(金额)", "客户 = '" & nm & "' And 已付款 = 'N'"
)
Next
DataTables(
"表B").ResumeRedraw()

在表A为5000行,客户数为1000的时候,执行上述代码所花费的时间为0.25秒,效率比之前提高了100倍。

但显然逻辑列是不可能不用的,是什么原因导致逻辑列的查询效率如此之低? 又有什么解决办法呢?
实际上 在DataTable中,逻辑列的值并不是以True和False存储的,而是以1和0存储的,当我们从DataTable中取值时,会自动将1转换为True,0转换为False后返回。
既然如此,我重新将已付款列改为逻辑型,然后修改代码,直接在表达式中用1和0代替True和False进行比较:

Dim nms As List(of String) = DataTables("表A").GetValues("客户")
DataTables(
"表B").StopRedraw()
For Each
nm As String In nms
    Dim
dr As DataRow = DataTables("表B").AddNew()
   
dr("客户") = nm
    dr
("付款合计") = DataTables("表A").Compute("Sum(金额)", "客户 = '" & nm & "' And 已付款 = 1")
   
dr("欠款合计") = DataTables("表A").Compute("Sum(金额)", "客户 = '" & nm & "' And 已付款 = 0")
Next
DataTables(
"表B").ResumeRedraw()

在表A为5000行,客户数为1000的时候,执行上述代码所花费的时间为0.23秒,效果非常好。

在查询表达式中用1代替True,用0代替False,效率提高超过100倍,切记切记。


本页地址:http://www.foxtable.com/webhelp/topics/2227.htm