テキストファイルからキーワードを拾って
SQLをなげています
SQLの質問になってしまうかもしれません
いまはADO接続でやっています

Open ファイル as input......

SQL = select * from tbl where name like '%キーワード%'
execute(SQL)

レコードセットの値で処理をいろいろ・・・
Loop

もともとのDBの件数がものすごくおおくてselect文に結構な時間が
かかってしまいます。速度をあげるほうほうってあるのでしょうか
私にはおもいつかなくて・・・

こういったほうほうは どう? ってのがありましたら
おしえていただきたいのですが よろしくおねがいします。

このQ&Aに関連する最新のQ&A

A 回答 (5件)

確かに・・・Like演算子・・・あまり使いたくないですね・・・


文字列比較は処理を遅くさせるし、増してや「=」ではなくLikeですから、膨大な時間がかかる恐れが・・・

ちなみにぼく自身、DB系を多くしています。今の仕事もDB系なのですが、元となるホストは他の会社が行っており、それにあわせて作らなければなりません。
で、そのホスト連携部分に文字列を比較しなければならない部分があるんですよ・・・・
自分の会社ならまだしも、他の会社がすでに設計済みのDBだから変えようがないのです。。。

まぁ愚痴っても仕方ないか・・・


なのでぼくも(不本意ながら)Like演算子を使用しています。


長い前置きはさておき・・・

本題のSQLのスピードなのですが、
http://homepage2.nifty.com/inform/vbdb/addnew.htm
こちらに面白い記述がありました。

AddNewにかかるスピードの検証で
Access データベースの場合: AddNew のほうが INSERT INTO より5倍以上速い
SQL Server の場合: INSERT INTO のほうが AddNew より 1.4倍 くらい速い
とあります。


たぶんで物を言ってはいけないと思うけど、言っちゃいます。

(1)もしDBがアクセスで
 >レコードセットの値で処理をいろいろ・・・
 のところがUpdate用のSQL文で処理を行ってる場合

 Recordsetをして、処理を行う


(2)もしDBがアクセス以外で
 >レコードセットの値で処理をいろいろ・・・
 のところがRecordsetで処理を行ってる場合

 Recordsetをせずに、UPDATE用のSQLを実行する


未検証なのですが多分イメージとして、こういうパターンが各DBに適してるのかな?

すでにこのパターンなのであれば、意味ないですね(^^;)

参考URL:http://homepage2.nifty.com/inform/vbdb/addnew.htm
    • good
    • 0

teebeeさん



AccessでもADOで接続したら、ワイルドカードは%なんですよ。
    • good
    • 1

ayato さん、こんばんは。


このSQLの書き方だと、ひょっとしてindexには期待できないのでしょうか...

ワイルドカードが"%"ってことは、少なくともアクセスじゃないなぁとかひょっとしたらOracle?とか、想像で書いてますが、ワイルドカードを使った検索でindex使えるのって前方一致の時だけじゃないです?
(有識者の方、間違ってたら指摘してください)

likeを使わなくちゃいけないの?とか気になっちゃいます。
他の列をキーにして検索できたりしないのでしょうか?

#なんか、逆に質問ばっかりになっちゃったみたいでごめんなさい。
    • good
    • 0

#1の方の通り、検索条件となるフィールドにインデックスを


作成することが一つあります。何でもつけていいというわけではありませんが。

また、プログラムの実装アルゴリズムですが、
DBの接続はSQLを発行するたびに接続しては遅いです。
さすがにayatoさんはつなぎっぱなしにしてますよね?
一度私はSQL発行ごとにDB接続をやってしまい、速度低下になってました(爆)。

また、検索条件があいまい検索をしなくてはいけないほど複雑なら、
テーブル設計に問題があることも考えられます。

ちょっとプログラムだけの話ではないですが、テーブル設計に問題がある可能性もあるということを知っていればいいかと思います。
    • good
    • 0

まず、likeを使ったあいまい検索は、全レコードを検索しますのでどうしてもパフォーマンスの低下が見られます。


可能であれば、使用を避けたほうが良いです。
その他には、テーブルに検索条件になるフィールドにインデックスを作成してみてはどうでしょうか。私の経験上かなりの改善が見られました。
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QSQLでSELECTの中でSELECT文を作りたいのですが。

開発環境 VB6 WINXP 
SQLで、次のそれぞれの文((1)、(2))は問題なく動作しますが、これを合体させて、絞り込むにはどうしたら良いのでしょうか。
(1) strSQLM = "SELECT * FROM 漁獲DATA WHERE 日付 =#" & Format(PickedDate, "m-d-yy") & "#"
(2) strSQLM = "SELECT * FROM 漁獲DATA WHERE 順位 =" & Meigara

つまり同一の日の同じ順位のデータを調べたいのですが。よろしくお願いします。

Aベストアンサー

>上の文だと、抽出条件でデータ型が一致しません。となってしまいました。どうすれば良いのでしょうか。Meigaraは数値です。

Meigaraは数値でしたか。自分は「○位」という感じの文字列だと思っていました。その場合は「順位 =」のあとにある「'」と一番最後にある「Meigara」から後ろを消せば良いです。消した場合のSQL文は下記になります。

strSQLM = "SELECT * FROM 漁獲DATA WHERE 日付 ='" & Format(PickedDate, "m-d-yy") & "' AND 順位 =" & Meigara

これで大丈夫なはずですよ。

QADO.NETのSqlDataReaderをADOのRecordSetのように使いたい

いつもお世話になっております。

SqlDataReaderについての質問なのですが、ADOでのレコードセットであった、EOFプロパティ(それに該当するものも)が見当たらず困っています。

レコードを最後まで書き出すことは、while(DataReader.read = True)でもできますが、ループの中に判定を入れて、条件次第ではレコードを進めないということができません。

ADO.NETのときはDO UNTIL RecordSet.Eof = True と、RecordSet.nextを組みせて柔軟に書き出しができていた分、ちょっと不便に感じています。

EOFと同様のプロパティというのもあるのでしょうか?

Aベストアンサー

お世話になります。

RecordSet.Eof = True
DataReader.Read = False
と同じです。

> ループの中に判定を入れて、条件次第ではレコードを進めないということができません。

以下の例では、SQL Server 2000 の Northwind データベースの
Cusomers テーブルから値を取得し、
標準出力に 1 列目の値を出力します。
ただし、
1 列目の値が "ANTON" の場合、読み込み及び出力の処理を中断しています。

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
  Dim con As SqlClient.SqlConnection = New SqlClient.SqlConnection(My.Settings.NorthwindConnectionString)
  Try
    con.Open()
    Dim sc As SqlClient.SqlCommand = New SqlClient.SqlCommand("SELECT * FROM Customers", con)
    Try
      Dim reader As SqlClient.SqlDataReader = sc.ExecuteReader()
      Try
        While (reader.Read())
          Dim str As String = reader.GetString(0)
          Console.WriteLine(str)
          If str = "ANTON" Then
            reader.Close()
            Exit While
          End If
        End While
      Finally
        If Not reader Is Nothing Then reader.Close()
      End Try
    Finally
      If Not sc Is Nothing Then sc.Dispose()
    End Try
  Finally
    If Not con Is Nothing Then con.Close() : con.Dispose()
  End Try
End Sub

お世話になります。

RecordSet.Eof = True
DataReader.Read = False
と同じです。

> ループの中に判定を入れて、条件次第ではレコードを進めないということができません。

以下の例では、SQL Server 2000 の Northwind データベースの
Cusomers テーブルから値を取得し、
標準出力に 1 列目の値を出力します。
ただし、
1 列目の値が "ANTON" の場合、読み込み及び出力の処理を中断しています。

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handle...続きを読む

QVB6+SQL サーバー 2000 で 実行時エラー '3704' がでます:

VB6 + SQL サーバー 2000 でDB接続を行っていますが
リストのように SELECT 文の後にInsert 文を実行しようとし
Re.Closeを実行すると
-------------------------------------------------------------
実行時エラー '3704':
オブジェクトが閉じている場合は、操作は許可されません
-------------------------------------------------------------
 とエラーになり、連続するSQL文を実行する場合のopen ,Close は
どのように書けばよろしいのでしょうか。

 ネット上で見つけた資料によるとメソッド RE.CancelUpdate を使うと
ありましたがこれもエラーとなります。

どなたか 教えていただけないでしょうか。

--- sample ----------------------------------------
Dim Cn As New ADODB.Connection
Dim Re As New ADODB.Recordset

Connect = ""
Connect = "Provider = SQLOLEDB;" _
& "Data Source = サーバー;" _
& "User ID = sa;" _
& "Password = パスワード;" _
& "initial Catalog = database;"
'
Cn.Open Connect
'
strSQL = "SELECT * from DBTBL WHERE CODE = '000001'"
Re.Open strSQL, Cn, adOpenKeyset 'SQL文を実行
Re.Close
'
strSQL = "Insert Into MAS1PF (CODE,NAME,TEL,FAX) Values('11111','名前','TEL,'FAX)"
Re.Open strSQL, Cn, adOpenKeyset 'SQL文を実行
'
Re.Close
Cn.Close

VB6 + SQL サーバー 2000 でDB接続を行っていますが
リストのように SELECT 文の後にInsert 文を実行しようとし
Re.Closeを実行すると
-------------------------------------------------------------
実行時エラー '3704':
オブジェクトが閉じている場合は、操作は許可されません
-------------------------------------------------------------
 とエラーになり、連続するSQL文を実行する場合のopen ,Close は
どのように書けばよろしいのでしょうか。

 ネット上で見つけた資料によるとメソッド ...続きを読む

Aベストアンサー

1:strSQL = "SELECT * from DBTBL WHERE CODE = '000001'"
2:Re.Open strSQL, Cn, adOpenKeyset 'SQL文を実行
3:Re.Close
4:strSQL = "Insert Into MAS1PF (CODE,NAME,TEL,FAX) Values('11111','名前','TEL,'FAX)"
5:Re.Open strSQL, Cn, adOpenKeyset 'SQL文を実行

の 3: で Re.Close したまま、5: で Re.Open しているからだと思います。
5: の前に
Set Re = New ADODB.Recordset
を入れると正常に動作するようになると思います。
ちなみに、なぜ 2: ではエラーが発生しないかというと、
Dim Re As ADODB.Recordset
ではなく、
Dim Re As New ADODB.Recordset
として宣言しているからです。

Qアクセス2000で作成したデータベースにテーブルを追加したいのです 「Set tbl = catDB.Tables![会費管理2]」 

アクセスで作成したデータベースがあります。
簡単にテーブルを追加するプログラムを作成したいのですが可能かしら?
現在[会費管理2]というテーブルが無いので[会費管理2]と言うテーブルを追加して、そのテーブルに各フィールドを作成したいのです。
作成したSet tbl = catDB.Tables![会費管理2] に
'以下追加したいフィールド
Set colAdo = New ADOX.Column
With colAdo
.Name = "数値1"
.Type = adInteger
.Attributes = adColNullable
End With
tbl.Columns.Append colAdo
Set colAdo = New ADOX.Column
With colAdo
.Name = "数値2"
.Type = adInteger
.Attributes = adColNullable
End With
tbl.Columns.Append colAdo
Set colAdo = New ADOX.Column
With colAdo
.Name = "数値3"
.Type = adInteger
.Attributes = adColNullable
End With
tbl.Columns.Append colAdo
Set colAdo = New ADOX.Column
With colAdo
.Name = "日付"
.Type = adDate
.Attributes = adColNullable
End With
tbl.Columns.Append colAdo
Set colAdo = New ADOX.Column
With colAdo
.Name = "金額"
.Type = adCurrency
.Attributes = adColNullable
End With
tbl.Columns.Append colAdo
Set colAdo = Nothing
Set tbl = Nothing
Set catDB = Nothing
cnn.Close
End Sub

アクセスで作成したデータベースがあります。
簡単にテーブルを追加するプログラムを作成したいのですが可能かしら?
現在[会費管理2]というテーブルが無いので[会費管理2]と言うテーブルを追加して、そのテーブルに各フィールドを作成したいのです。
作成したSet tbl = catDB.Tables![会費管理2] に
'以下追加したいフィールド
Set colAdo = New ADOX.Column
With colAdo
.Name = "数値1"
.Type = adInteger
.Attributes = adColNullable
End With
tbl.Columns.Append colAdo
Set colAdo = New ADOX...続きを読む

Aベストアンサー

大変申し訳ございません。
私の勉強不足と思います。

> Set tbl = catDB.Tables![会費管理2]

テーブルが無い時点で、上記はエラーとなる気がします。
というより、
![会費管理2]
という記述したことが無いので、申し訳ありません。

私では解決できないと思いますので、他の方の回答を待ってください。

失礼いたしました。

QRst.FindFirst "名称コード" & "=" & "'101'"

タイトルのコードでは問題ないのですが、 101 を文字変数にすると「抽出条件でデータ型が一致していません」のエラーになります。この場合シングルクオーテーションはどういう意味なのでしょうか。
どうすれば良いのでしょうか。

dim Vcode as string
Vcode = "101"
Rst.FindFirst "名称コード" & "=" & Vcode

Aベストアンサー

FindFirst や、フォームの Filter プロパティで設定する場合は、SQL文のWHERE句の
内容を設定する必要があります。

フィールド名がテキスト型の場合は、

SELECT * FROM テーブル名 WHERE フィールド名 = "xxx"

のようになります。
で、FindFirst メソッドなんかで使う場合は、

rst.FindFirst フィールド名 = "xxx"

としたいところですが、条件の部分は文字列にしないといけません。
で、

rst.FindFirst "フィールド名 = "xxx""

こうすると、

フィールド名 =

で、切れてしまいます。
そこで、

rst.FindFirst "フィールド名 = 'xxx'"

このようにすればOKです。
次のステップとして、xxx の部分を変数を使ってやりたい場合。
単純に変数名に置き換えると、

rst.FindFirst "フィールド名 = '変数名'"

ですが、変数を、"" の中に記述すると、文字列として扱われますので、"" の外に
出してやる必要があります。
その場合、文字列と変数をつなぐためには、& を使います。

rst.FindFirst "フィールド名 = '" & 変数名 & "'"

で、このようになります。

FindFirst や、フォームの Filter プロパティで設定する場合は、SQL文のWHERE句の
内容を設定する必要があります。

フィールド名がテキスト型の場合は、

SELECT * FROM テーブル名 WHERE フィールド名 = "xxx"

のようになります。
で、FindFirst メソッドなんかで使う場合は、

rst.FindFirst フィールド名 = "xxx"

としたいところですが、条件の部分は文字列にしないといけません。
で、

rst.FindFirst "フィールド名 = "xxx""

こうすると、

フィールド名 =

で、切れてしまいます...続きを読む


このQ&Aを見た人がよく見るQ&A

このカテゴリの人気Q&Aランキング

おすすめ情報