找回密码
 加入
搜索
查看: 22011|回复: 37

[原创] 10万笔(55万笔)数据 汇入 LISTVIEW 实测……. 只要15秒(LISTVIE汇数据最佳写法)

 火... [复制链接]
发表于 2012-8-20 13:36:48 | 显示全部楼层 |阅读模式
本帖最后由 kk_lee69 于 2012-8-20 13:39 编辑

因为工作上的需要  经常要与 数据库沟通….所以做了个小测试 把心得整理出来…….

传统方法是  一笔一笔的汇数据 如下所示….但是数据量一大的时候 就会变很慢……10万笔数据 实际测试大约 需要500秒



Dim $Server = "DBSERVERSQL"
Dim $Company = "Z100A01001"
DIM $array[1][1]


#include <GuiConstantsEx.au3>
#include <GuiListView.au3>
#include <array.au3>
#include <Date.au3>
#include <GuiConstants.au3>
#include <WindowsConstants.au3>
#include <Constants.au3>

#RequireAdmin


$WinMain = GuiCreate('TEST',800,600)

$menu2 = GuiCtrlCreateButton('RUN', 210, 30, 150, 30); 
GUICtrlSetFont(-1,10)

$ListView1 = GUICtrlCreateListView("a  |b  |c   |d  |e  |f  |g  ", 32, 100, 705, 401)


$conn = ObjCreate("ADODB.Connection")
$RS = ObjCreate("ADODB.Recordset")
$conn.Open ("driver={SQL Server};server="&$Server&";uid=sa;pwd=123;database="&$Company);

$RS.ActiveConnection = $conn;

GuiSetState()

While 1
        
        Switch GUIGetMsg()

                Case $GUI_EVENT_CLOSE
                        Exit

                Case $menu2
                        

                        $iTimer = TimerInit()
                        $RS.open ("SELECT  LA001,LA004,LA006,LA007,LA008,LA009,LA010 FROM INVLA Where LA010 like 'AMB%'");
                        
                        While (Not $RS.eof And Not $RS.bof);

                                GUICtrlCreateListViewItem($RS.Fields(0).value&"|"&$RS.Fields(1).value&"|"&$RS.Fields(2).value&"|"&$RS.Fields(3).value&"|"&$RS.Fields(4).value&"|"&$RS.Fields(5).value&"|"&$RS.Fields(6).value, $ListView1 )
                                

                                $RS.movenext;
                        WEnd;
                        $RS.close;

                        
                

                        
            MsgBox(4160, "Information", "Load time: " & TimerDiff($iTimer) / 1000 & " seconds")
                        
        EndSwitch

WEnd



如果改成先将 取得的数据 放入到数组里面…. 在一次汇入 LISTVIEW 这样就大约 只需要15秒   如果数据是55万笔 也只要 85秒左右   如下所示:



Dim $Server = "DBSERVERSQL"
Dim $Company = "Z100A01001"
DIM $array[1][1]


#include <GuiConstantsEx.au3>
#include <GuiListView.au3>
#include <array.au3>
#include <Date.au3>
#include <GuiConstants.au3>
#include <WindowsConstants.au3>
#include <Constants.au3>

#RequireAdmin


$WinMain = GuiCreate('TEST',800,600)

$menu2 = GuiCtrlCreateButton('RUN', 210, 30, 150, 30); 
GUICtrlSetFont(-1,10)

$ListView1 = GUICtrlCreateListView("a  |b  |c   |d  |e  |f  |g  ", 32, 100, 705, 401)


$conn = ObjCreate("ADODB.Connection")
$RS = ObjCreate("ADODB.Recordset")
$conn.Open ("driver={SQL Server};server="&$Server&";uid=sa;pwd=123;database="&$Company);

$RS.ActiveConnection = $conn;



GuiSetState()
; 顯示視窗


While 1
        
        Switch GUIGetMsg()

                Case $GUI_EVENT_CLOSE
                        Exit



                Case $menu2
                        

                        $RS.open ("SELECT COUNT(*) FROM INVLA Where LA010 like 'AMB%'");
                        
                        While (Not $RS.eof And Not $RS.bof);
                                $P=$RS.Fields(0).value
                                $RS.movenext;
                        WEnd;
                        $RS.close;

                        
                        Dim $APP[$P][7]
                        
                        
                        $i=0 
                        $iTimer = TimerInit()
                        $RS.open ("SELECT  LA001,LA004,LA006,LA007,LA008,LA009,LA010 FROM INVLA Where LA010 like 'AMB%'");
                        
                        While (Not $RS.eof And Not $RS.bof);

                                $APP[$i][0]=$RS.Fields(0).value
                                $APP[$i][1]=$RS.Fields(1).value
                                $APP[$i][2]=$RS.Fields(2).value
                                $APP[$i][3]=$RS.Fields(3).value
                                $APP[$i][4]=$RS.Fields(4).value
                                $APP[$i][5]=$RS.Fields(5).value
                                $APP[$i][6]=$RS.Fields(6).value
                                
                                $i=$i+1
                                
                                ;GUICtrlSetState($SETDATA,$GUI_ENABLE)
                                $RS.movenext;
                        WEnd;
                        $RS.close;

                        
                
                        _GUICtrlListView_AddArray($ListView1, $APP)
                        
            MsgBox(4160, "Information", "Load time: " & TimerDiff($iTimer) / 1000 & " seconds")
                        
        EndSwitch

WEnd







这是 目前 发现最好的写法了  欢迎 有更好写法的朋友 提出来讨论
发表于 2012-8-20 18:15:51 | 显示全部楼层
如果数据量大。。我一般会采用分段方式
发表于 2012-8-23 06:46:40 | 显示全部楼层
本帖最后由 athland5013 于 2012-8-23 06:50 编辑

回复 1# kk_lee69
;$P = Number($conn.Execute("SELECT COUNT(*) FROM INVLA Where aa").GetString)
;_GUICtrlListView_SetItemCount($ListView1, $P)

$APP = $conn.Execute("SELECT  id,bb,cc,dd,ee,ff,gg FROM INVLA").GetRows        
_GUICtrlListView_AddArray($ListView1, $APP)
基本上 Case $menu2  那段代码可以写成这样, .GetRows        就是返回一个二维数组,效率比添加.Fields高很多

如果 $ListView1 是句柄而不是ID的话,这两句就显得有必要了
;$P = Number($conn.Execute("SELECT COUNT(*) FROM INVLA Where aa").GetString)
;_GUICtrlListView_SetItemCount($ListView1, $P)

如果要求极致的话,可以修改_GUICtrlListView_AddArray函数,减少不必要的判断

但_GUICtrlListView_AddArray不能用_GUICtrlListView_SortItems排序
要排序需要
修改 DllStructSetData($tItem, "Mask", BitOR($LVIF_TEXT, $LVIF_PARAM))
添加 DllStructSetData($tItem, "Param", _SendMessage($hWnd, $LVM_GETITEMCOUNT) + 11111111)
 楼主| 发表于 2012-8-23 09:32:13 | 显示全部楼层
本帖最后由 kk_lee69 于 2012-8-23 09:45 编辑

回复 4# athland5013
感謝回復  受益良多... 現在在上班  晚點來研究您提到的部分...多謝指正

但_GUICtrlListView_AddArray不能用_GUICtrlListView_SortItems排序
要排序需要
修改 DllStructSetData($tItem, "Mask", BitOR($LVIF_TEXT, $LVIF_PARAM))
添加 DllStructSetData($tItem, "Param", _SendMessage($hWnd, $LVM_GETITEMCOUNT) + 11111111)


這個部份我不懂呢 ?? DllStructSetData 要在哪修改呢  能寫個範例嗎??
发表于 2012-9-4 23:41:12 | 显示全部楼层
谢谢楼主提供,支持你
发表于 2013-7-21 23:04:36 | 显示全部楼层
没看懂,值得学习
发表于 2013-8-16 15:02:02 | 显示全部楼层
这个是很有用的程序,谢谢
发表于 2013-8-16 16:18:35 | 显示全部楼层
正在学习数组在AU3脚本代码中的应用知识,感觉这方面的初学资料很少,但又很重要。尤其是多维数组在脚本中的使用方法,感觉一下子很难吃透,要是多一些这样的资料指引就好了。
发表于 2013-8-20 19:47:49 | 显示全部楼层
嗯,分析的不错,研究下
发表于 2013-9-10 09:27:30 | 显示全部楼层
这个支持,我也是这样弄的,都读到数组再写LISTVIEW
发表于 2013-9-10 10:53:41 | 显示全部楼层
谢谢楼主分享。
发表于 2013-9-12 18:46:31 | 显示全部楼层
慢慢消化,谢谢分享
发表于 2013-10-4 13:02:47 | 显示全部楼层
谢谢楼主提供
发表于 2013-12-25 17:55:38 | 显示全部楼层
回复 5# kk_lee69


  4#说的是要修改下_guictrllistview_Addarray 这个UDF
发表于 2014-2-13 06:38:01 | 显示全部楼层
现在还没有碰到这么大的数据量,先记录!
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-11-17 01:38 , Processed in 0.078574 second(s), 19 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表