2

主に文字列データと一意の ID 列を持つ 3 つのテーブルがあります。

categories ~45 rows
clientfuncs ~800 rows
serverfuncs ~600 rows

すべてのテーブルには、一意のプライマリ AI 列「id」があります。私は1つのクエリで行を数えようとしています:

SELECT COUNT(categories.id), COUNT(serverfuncs.id), COUNT(clientfuncs.id) FROM categories, serverfuncs, clientfuncs

1.5 ~ 1.7 秒かかります。

そして試してみると

SELECT COUNT(categories.id), COUNT(serverfuncs.id) FROM categories, serverfuncs

また

SELECT COUNT(categories.id), COUNT(clientfuncs.id) FROM categories, clientfuncs

また

SELECT COUNT(clientfuncs.id), COUNT(serverfuncs.id) FROM clientfuncs, serverfuncs

、0.005 ~ 0.01 秒かかります。(あるべき姿)

誰かが説明できますか、これの理由は何ですか?

4

4 に答える 4

6

45*800*600 行のクロス結合を行っている場合、カウントの結果を確認すると気付くでしょう :-)

代わりにこれを試してください:

SELECT 
  (SELECT COUNT(*) FROM categories), 
  (SELECT COUNT(*) FROM serverfuncs), 
  (SELECT COUNT(*) FROM clientfuncs);
于 2013-09-16T14:07:06.583 に答える
5

結合条件が適用されていないため、クエリはデカルト積を実行しています。

1 query : 800*600*45 = 21,6 mil
2 query : 45*600     = 27 k
3 query : 45*800 ...
于 2013-09-16T14:06:14.697 に答える
2

まず、FROM 句で 3 つのテーブルを使用して、各テーブルに固有のカウントを計算しますか? これにより、SELECT ステートメントが 3 つのテーブルのデカルト積を生成し、合計行数が 45 x 800 x 600 になり、そこからカウントが計算されます。したがって、categories.id 値の多くの重複がカウントされ、他のカウントも同様です。いずれにせよ、FROM 句で最初の 2 つのテーブルを使用すると、デカルト積には 45 X 800 行しか含まれず、3 つのテーブルが生成する行よりもはるかに少なくなります。したがって、2 つのテーブルを使用したクエリははるかに高速です。この場合、主キーは役に立ちません。

各テーブルからカウントを取得するには、3 つの異なるステートメントを使用することをお勧めします。

それでも一度にカウントを取得したい場合は、次の構文を使用できます。

SELECT (SELECT COUNT(categories.id) FROM categories), 
       (SELECT COUNT(serverfuncs.id) FROM serverfuncs), 
       (SELECT COUNT(clientfuncs.id) FROM clientfuncs);

RDBMS が FROM 句のない SELECT ステートメントをサポートしている場合。これらは正しいカウントを提供し、非常に高速になります。

于 2013-09-16T14:19:23.043 に答える
2

これは、クエリがテーブルを個別にカウントするのではなく、テーブルを結合しているためです (クエリの最後の部分のコンマは結合の省略形です)。そのため、テーブルが 2 つだけのクエリは高速になります。

于 2013-09-16T14:08:24.420 に答える