DOBON.NET DOBON.NETプログラミング掲示板過去ログ

[VB.NET2003]データグリッド書き込みが遅い

分類:[.NET]

こんにちは
ODBC.DataCommandを使ってMySQLから持ってきたレコードをDataGridに書き込む
プログラムを作っていますが、DataGridへの書き込みが恐ろしく遅いです。
100件のデータを書き込むのに約45秒かかります。

Private Sub DataInsertForGrid(ByVal dr2)
Do While dr2.Read = True
DataTable1.Rows.Add(DataTable1.NewRow())
Dim WritePointer = 0
For WritePointer = 0 To MaxKensakucol
Me.DataGrid1.Item(RowMakeCounter, WritePointer) = dr2.Item(WritePointer)
Next
RowMakeCounter += 1
Loop
End Sub

Debug情報で処理時間を吐き出させてみたところ、SQL文ではなく、
データの書き込みが遅いことは明白でした。
DataGridの書き込み処理は遅いものなのでしょうか?
それとも単にプログラムが不味いだけでしょうか?
お世話になります。

比較していないので速さはわかりませんが、
DataAdapter を使って Fill した方が楽なのでは?
Dim OleCon As OleDb.OleDbConnection = New OleDb.OleDbConnection(接続文字列)
OleCon.Open()
Dim da As OleDb.OleDbDataAdapter = New OleDb.OleDbDataAdapter
da.SelectCommand = New OleDb.OleDbCommand
da.SelectCommand.CommandText = "SELECT ..."
da.SelectCommand.Connection = OleCon

Dim dt As DataTable = New DataTable
da.Fill(dt)
Me.DataGrid2.DataSource = dt

■No14648に返信(あおぞらさんの記事)
型が書いてないのですが、
(Option Strict Off になっているのかな?)

dr2 ← OleDb.OleDataReader 型
DataTable1 ← DataTable 型
WritePointer ← Integer 型
MaxKensakucol ← Integer 型

という事でしょうか。
DataTable1 は何の為に?
■No14651に返信(なおこ(・∀・)さんの記事)
> お世話になります。
>
> 比較していないので速さはわかりませんが、
> DataAdapter を使って Fill した方が楽なのでは?
> Dim OleCon As OleDb.OleDbConnection = New OleDb.OleDbConnection(接続文字列)
> OleCon.Open()
> Dim da As OleDb.OleDbDataAdapter = New OleDb.OleDbDataAdapter
> da.SelectCommand = New OleDb.OleDbCommand
> da.SelectCommand.CommandText = "SELECT ..."
> da.SelectCommand.Connection = OleCon
>
> Dim dt As DataTable = New DataTable
> da.Fill(dt)
> Me.DataGrid2.DataSource = dt
>
> ■No14648に返信(あおぞらさんの記事)
> 型が書いてないのですが、
> (Option Strict Off になっているのかな?)


なおこ(・∀・)様
返信ありがとうございます。
もともとはDataAdapterで記述していたのですが、速度が上がらず原因を
探しているうちに、MSのサイトでDataAdapterはXMLにシリアル化されるの
で遅い(http://www.microsoft.com/japan/msdn/vs05/aspnet/dataaccess.aspより)
とのことで書き直しました。
>
> dr2 ← OleDb.OleDataReader 型
> DataTable1 ← DataTable 型
> WritePointer ← Integer 型
> MaxKensakucol ← Integer 型
>
> という事でしょうか。
正解です。
> DataTable1 は何の為に?
これがないと例外が出ます。
浅学なので間違っているかもしれませんがDataGridに連結したセルを
書き込む前に増やしていると理解しています。
Fillだとループまわしたりとかしなくて良いから楽なんですが・・・・
お世話になります。

■No14654に返信(あおぞらさんの記事)
> もともとはDataAdapterで記述していたのですが、速度が上がらず原因を
> 探しているうちに、MSのサイトでDataAdapterはXMLにシリアル化されるの
> で遅い(http://www.microsoft.com/japan/msdn/vs05/aspnet/dataaccess.aspより)
> とのことで書き直しました。

リンク先のページは、ASP.NET 2.0 について書かれていますが、
Visual Web Developer 2005 Express Edition とかを使って開発されているのですか?
というか、そもそも Web アプリケーションでのお話なのですか?
早い返信に感謝いたします。

■No14681に返信(なおこ(・∀・)さんの記事)
> お世話になります。
>
> ■No14654に返信(あおぞらさんの記事)
>>もともとはDataAdapterで記述していたのですが、速度が上がらず原因を
>>探しているうちに、MSのサイトでDataAdapterはXMLにシリアル化されるの
>>で遅い(http://www.microsoft.com/japan/msdn/vs05/aspnet/dataaccess.aspより)
>>とのことで書き直しました。
>
> リンク先のページは、ASP.NET 2.0 について書かれていますが、
> Visual Web Developer 2005 Express Edition とかを使って開発されているのですか?

あら、本当だ・・・「DataGrid 書き出し 遅い」のキーワードで検索して出てきて、
かつ.net1.1とあったのでこのことだと・・・
使っているのは.net2003です。
> というか、そもそも Web アプリケーションでのお話なのですか?
WindowsFormのDatagridです。
ASPではない(=Webアプリケーションではない?)です。
お世話になります。

DataTable1 って、
きっと DataGrid1 の DataSource になっているのですよね?

以下の 2 つで実験しましたが、
断然 Fill して Bind した方が早かったですが...。
(データは 830 件で、遅い方でも 1 秒ちょっとです)

'DataTable
Private Sub Button7_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button7.Click
  Dim startDate As DateTime = DateTime.Now

  Dim con As SqlClient.SqlConnection = New SqlClient.SqlConnection
  con.ConnectionString = "Server=(local);Database=northwind;Trusted_Connection=True;"
  con.Open()

  Dim dt As DataTable = New DataTable
  Dim da As SqlClient.SqlDataAdapter = New SqlClient.SqlDataAdapter
  da.SelectCommand = New SqlClient.SqlCommand
  da.SelectCommand.CommandText = "SELECT CustomerID FROM Orders"
  da.SelectCommand.Connection = con
  da.Fill(dt)
  da.SelectCommand.Dispose()
  da.Dispose()
  con.Close()
  con.Dispose()

  Me.DataGrid2.DataSource = dt
  Dim endDate As DateTime = DateTime.Now

  Me.Label2.Text = ((endDate.Second * 1000 + endDate.Millisecond) - (startDate.Second * 1000 + startDate.Millisecond)).ToString()
End Sub

'DataReader
Private Sub Button8_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button8.Click
  Dim startDate As DateTime = DateTime.Now

  Dim con As SqlClient.SqlConnection = New SqlClient.SqlConnection
  con.ConnectionString = "Server=(local);Database=northwind;Trusted_Connection=True;"
  con.Open()

  Dim dt As DataTable = New DataTable
  dt.Columns.Add("CustomerID", GetType(String))
  Me.DataGrid3.DataSource = dt

  Dim cmd As SqlClient.SqlCommand = New SqlClient.SqlCommand
  cmd.CommandText = "SELECT CustomerID FROM Orders"
  cmd.Connection = con
  Dim dr As SqlClient.SqlDataReader = cmd.ExecuteReader(CommandBehavior.CloseConnection)
  Dim rowCount As Integer = 0
  While dr.Read
    dt.Rows.Add(dt.NewRow())
    Me.DataGrid3.Item(rowCount, 0) = dr.Item(0)
    rowCount += 1
  End While
  dr.Close()
  cmd.Dispose()
  con.Close()
  con.Dispose()

  Dim endDate As DateTime = DateTime.Now
  Me.Label3.Text = ((endDate.Second * 1000 + endDate.Millisecond) - (startDate.Second * 1000 + startDate.Millisecond)).ToString()
End Sub
早い返信に感謝いたします。
なおこ(・∀・)様
コードまで載せていただきありがとうございます。
早速使ってみようと思ったのですが、・・・
今までMySQLにODBCConnectionを使っていたのですが、
コードを見るとSQLConnectionになっているのでフォームデザイナから
やってみようとしました。
SqlDataAdapterの接続ウィザードでMicrosoft OLE Provider For ODBC Drivers
を選択し(ODBCDataAdapterの時に出ていたMySqlODBCDroverが出ていないので)、
接続テストボタンを押したら接続成功と出たので、そのままOKを押したら、
作成した接続は現在のデータアダプタでは動作しませんというエラーが出てしまいました。

コード的には似ているのですがDataAdapterが違うだけで処理速度がこんなに
変わるものなのかなぁ・・・
もう少しあがいてみます。アドバイスがあれば是非 是非ともよろしくお願いします。
遅い原因が分かりました。
データソースのトレースがONになっていました。
トレースをOFFにしたら1秒くらいで表示できました。
なおこ(・∀・)様 本当にありがとうございました。

これにて解決とさせていただきます。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板