3

30,000 を超えるテーブルと、各テーブルに最大 40 ~ 100 行のデータベースがあります。特定の列の下に文字列を含むテーブル名のリストを取得したいと考えています。

たとえば、次のようになります。

「foo」を含むすべてのテーブルの名前を取得したい...

Database
    Table_1
        ID: 1, STR: bar
        ID: 2, STR: foo
        ID: 3, STR: bar
    Table_2
        ID: 1, STR: bar
        ID: 2, STR: bar
        ID: 3, STR: bar
    Table_3
        ID: 1, STR: bar
        ID: 2, STR: bar
        ID: 3, STR: foo

したがって、この場合、関数は ['Table_1', 'Table_3'] を返す必要があります。

これまでのところ、問題なく動作しますが、実行に 2 分以上かかります。これは、私が考えているアプリケーションには長すぎます。

self.m('SHOW TABLES')
result = self.db.store_result()
tablelist = result.fetch_row(0, 1)
for table in tablelist:
    table_name = table['Tables_in_definitions']
    self.m("""SELECT `def` FROM `""" + table_name + """` WHERE `def` = '""" + str + """'""")
    result = self.db.store_result()
    r = result.fetch_row(1, 1)
    if len(r) > 0:
        results.append(table_name)

私はこれをスピードアップする方法を思いつくほど頭が良くないので、誰か提案があれば大歓迎です、ありがとう!

4

1 に答える 1

3

である各テーブルに 1 つの行が存在するかどうかをテストするだけの場合は、クエリの最後に句をdef = 'str'追加するだけで簡単に実行できます (他の変更は必要ありません) 。LIMIT 1

(クエリが完全なテーブル スキャンを実行している場合、MySQL は最初の行が見つかるとそれを停止できます。行が見つからない場合、完全なテーブル スキャンはテーブルの最後まで実行する必要があります。)

これにより、クライアントに返される大量の行を準備し、必要がない場合はそれらをクライアントに返すというオーバーヘッドも回避されます。

defまた、クエリが「干し草の山の中の針」を求めて大きなテーブルを検索している場合、先頭の列として (少なくとも最大のテーブルでは)インデックスを使用すると、パフォーマンスが向上する可能性があります。


アップデート:

あなたの質問を読み直しましたが、チェックするテーブルが 30,000 あることがわかりました。これは、30,000 の個別のクエリ、データベースへの 30,000 のラウンドトリップです。(ACCCKKK.)

したがって、私の以前の提案はほとんど役に立ちません。(それぞれが 30,000 行を含む 40 個のテーブルの場合は、より適切です。)

別のアプローチは、これらのテーブルの束を同時にクエリすることです。ただし、一度に数百を超えるテーブルを試すことさえためらうので、バッチで行います。

SELECT DISTINCT 'Table1' AS table_name FROM Table1 WHERE def = 'str'
 UNION ALL
SELECT DISTINCT 'Table2' FROM Table2 WHERE def = 'str'
 UNION ALL
SELECT DISTINCT 'Table3' FROM Table3 WHERE def = 'str'

各テーブルで一意である場合def、またはほぼ一意であり、返される重複する table_name 値を処理できる場合は、DISTINCT キーワードを取り除くことができます。

リスト内のすべてのテーブルに という名前の列があることを確認する必要がありますdef。その列が含まれていないテーブルに遭遇すると、バッチ全体が失敗します。そして、SHOW TABLES列名のそのチェックは行いません。という名前の列を持つテーブル名のリストを取得するには、次のようなクエリを使用しますdef

SELECT table_name
  FROM information_schema.columns
 WHERE table_schema = DATABASE()
   AND column_name = 'def'
 GROUP BY table_name
 ORDER BY table_name
于 2012-07-18T19:56:02.513 に答える