2013-03-19 74 views
1

我正在寫一個PowerShell腳本,從數據庫中提取任意的SQL查詢。這些查詢可能會變得非常大,在嘗試sqlcmd後,我最終得到了StreamWriter/SqlCommand組合。我遇到的問題是執行速度有點慢。像10倍一樣慢。我被告知它應該更快,因此問題。 要代碼!Powershell SqlCommand和StreamWriter慢寫

   $conn.ChangeDatabase("MyDB") 
       $mycmd = new-object System.Data.SqlClient.SqlCommand($Myquery, $conn) 
       $mycmd.CommandType = [System.Data.CommandType]::Text 
       $mycmd.CommandTimeout = 300 
       echo "Executing Reader."   
       $Results = $mycmd.ExecuteReader() 


       echo "Opening file for writing."      
       $sw2 = new-object system.IO.StreamWriter($sqlOutput, 1) 
       echo "File Opened for Writing."  
       $delimiter = "," 
       echo "Starting Row Reading" 
       $Counter = $Results.FieldCount 
       echo $Counter 
       # Put in header row on first execution. 
       $currtext = "" 
       if ($Counter -gt 0) 
       { 
        echo "Writing Header Row as:" 
        for ($i = 0; $i -lt $Counter; $i++) 
        { 
         $currtext = $currtext + $Results.GetName($i) 
         if ($i -lt $Counter - 1) 
         {$currtext = $currtext + $delimiter} 
        } 

        echo $currtext 
        $sw2.writeline($currtext) 
        $firstexecution = 0 
       } 
       else 
       { 
        $sw2.writeline("No Data Found") 
       } 

       $rowcount = 0 
       while ($Results.Read()) 
       { 
        $rowcount = $rowcount + 1 
        #echo "Reading Row" 
        $i = 0 
        $currtext = "" 
        for ($i = 0; $i -lt $Counter; $i++) 
        { 
         #echo "Processing Row" 
         $currtext = $currtext + """" + [string]$Results[$i] + """" 
         if ($i -lt $Counter - 1) 
          { $currtext = $currtext + $delimiter } 
        } 
        #echo "Writing Line." 
        #echo $currtext 
        $sw2.writeline($currtext) 
       } 
       echo "Total Rowcount:" + $rowcount 
       $sw2.flush() 
       $sw2.close() 
       $sw2.dispose() 
       $Results.close() 

任何人都知道我在做什麼錯誤/如何解決它?通過行

$DBComputers = Invoke-Sqlcmd -ServerInstance $SQLServer -Username $SQLUsername -Password $SQLPassword ` 
-Database $SQLDatabase -Query "SELECT * FROM Physical WHERE Retired=0 AND OS LIKE '%Windows%' ORDER BY Name" 

Iteriate:

+0

如果你真的說它變慢時,它會有很多幫助。在劇本中你有很多回應,那麼在它真的很慢之前最後一條消息是什麼?此外,sqlcmd可能會更快(我還沒有測試過),因爲使用powershell時需要生成對象等,而sqlcmd只需寫下未分析的行。 – 2013-03-19 17:07:33

+0

從性能的角度來看,重要的塊是逐行讀取,即while循環的部分。 while循環可以每分鐘讀取/寫入大約五兆字節的數據,這看起來很慢。 – 2013-03-19 17:23:45

回答

2

添加Snapins:

Add-PSSnapin SqlServerCmdletSnapin100 
Add-PSSnapin SqlServerProviderSnapin100 

打電話給你的變量:

$SQLUsername  = "user" 
$SQLPassword  = "password" 
$SQLDatabase  = "database" 
$SQLServer   = "localhost" 

抓住你的數據

foreach ($DBComputer in $DBComputers) { 

    Write-Host $DBComputer.Name ##$DBComputer.COLUMNNAME 

} 

通過使用上面的示例,我已經使用PowerShell完成了大量SQL。上面的例子查詢戴爾R720服務器上SQL標準實例的數據,速度相當不錯。這是Microsoft Access數據庫還是一個真正的SQL實例? Access Engine並不理想,根據您的磁盤類型不同,重要的問題也很重要。

您提到了一個大型數據集,我認爲最重要的是確保數據庫建立索引並運行真正的SQL引擎,而無需從非代碼角度更多地瞭解數據庫。

+0

這是一個真正的SQL實例,由於查詢是任意的,所以結構並不重要。數據吞吐量是問題所在。問題相當大,在我最近遇到的情況下,數據大約爲100MB。我之前使用過SQLCMD,但誤診了一個內存/大小問題(我寫入ZIP文件的緩衝區內存不足100MB),並將其重寫爲使用StreamWriter。我很好奇爲什麼我的表現差距如此之大。 – 2013-03-19 17:21:05

+0

你可能會做不必要的循環?不完全確定,但是可以使用該示例,只需執行以下操作即可將所有內容以單行形式呈現爲CSV格式,因爲這正是您正在做的事情,只需手動完成。 'Invoke-Sqlcmd -Query「SELECT * FROM Physical」| Export-Csv -Path C:\ Export.csv -NoTypeInformation' – tkrn 2013-03-19 17:32:34

+0

Export-Csv是否管理現場報價? Invoke-Sqlcmd提供了選擇分隔和導出的選項,但輸出沒有像需要的那樣乾淨利落。作爲一個方面說明,我以前的實現是:sqlcmd -Q $ Myquery -d $ CurrentDB -S $ CurrentServer -o $ sqlOutput -E -k -W -s「\t」-t 500 – 2013-03-19 17:59:17