2016-09-29 34 views
1

ヌル以外の列のカウントをwhere-partsのない1つのテーブルで使用すると、オプティマイザはそのテーブルの行数を返します。主キーのmariadb最適化が機能しない

PRIMARY KEYのように、UNIQE以外のNULL列のDISTINCT数を求める場合は、答えは同じである必要がありますが、今回はmariadbが計算を行います。

他のテーブルにjoinを残してもwhere-partsがない場合、結果はそのテーブルの行数になります。

mariadbがthous最適化を使用していない理由はありますか?大文字小文字が区別されない主キーのDISTINCTカウントが、そのテーブル内の行数に他の結果を与える可能性がありますか?

場合:JOINの主キー

DESCRIBE SELECT COUNT(DISTINCT our_article_id) FROM products; 
+------+-------------+----------+-------+---------------+---------+---------+------+--------+-------------+ 
| id | select_type | table | type | possible_keys | key  | key_len | ref | rows | Extra  | 
+------+-------------+----------+-------+---------------+---------+---------+------+--------+-------------+ 
| 1 | SIMPLE  | products | index | NULL   | PRIMARY | 152  | NULL | 225089 | Using index | 
+------+-------------+----------+-------+---------------+---------+---------+------+--------+-------------+ 

、第3回PRIMARY KEYにDISTINCT、左側の

CREATE TABLE products (
    our_article_id varchar(50) CHARACTER SET utf8 NOT NULL, 
    ..., 
    PRIMARY KEY(our_article_id) 
); 

CREATE TABLE product_article_id (
    article_id varchar(255) COLLATE utf8_bin NOT NULL, 
    our_article_id varchar(50) CHARACTER SET utf8 NOT NULL, 
    ... 
    PRIMARY KEY(article_id), 
    INDEX(our_article_id) 
); 

カウントクエリ、第一、基本的な数

DESCRIBE SELECT COUNT(our_article_id) FROM products;   
+------+-------------+-------+------+---------------+------+---------+------+------+------------------------------+ 
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra      | 
+------+-------------+-------+------+---------------+------+---------+------+------+------------------------------+ 
| 1 | SIMPLE  | NULL | NULL | NULL   | NULL | NULL | NULL | NULL | Select tables optimized away | 
+------+-------------+-------+------+---------------+------+---------+------+------+------------------------------+ 

第二DISTINCT WHERE-partsなしで

DESCRIBE SELECT COUNT(DISTINCT our_article_id) FROM products LEFT JOIN product_article_id USING (our_article_id); 
+------+-------------+--------------------+-------+---------------+---------+---------+----------------------------------+--------+-------------+ 
| id | select_type | table    | type | possible_keys | key  | key_len | ref        | rows | Extra  | 
+------+-------------+--------------------+-------+---------------+---------+---------+----------------------------------+--------+-------------+ 
| 1 | SIMPLE  | products   | index | NULL   | PRIMARY | 152  | NULL        | 225089 | Using index | 
| 1 | SIMPLE  | product_article_id | ref | PRIMARY  | PRIMARY | 152  | testseek.products.our_article_id | 12579 | Using index | 
+------+-------------+--------------------+-------+---------------+---------+---------+----------------------------------+--------+-------------+ 
+0

テーブル定義にエンジンを設定していません。 InnoDBまたはMyISAMを使用していますか? –

+1

私のデフォルトの設定があります:ENGINE = InnoDB –

+0

この場合、NULLでない一意の列にDISTINCTが必要な状況になるでしょうか?その結果は、その列の通常のカウントとどのように異なるでしょうか? – Mjh

答えて

2

"mariadbがthous最適化を使用していない理由はありますか?" - MySQL/MariaDBには数千の最適化機能がありません。それは欠けている。歴史を見てみましょう。

MySQLは約2 0年前に、リーンで平均的なデータベースエンジンとして開始されました。それは、ほとんどの人が必要とする機能に焦点を当て、オーバーヘッドを最小限に抑えました。これは、まれな最適化の多くが初期のリリースではなく、十分に重要と思われる場合にのみ追加されることを意味しました。

たとえば、PRIMARY KEYとします。 UNIQUEと定義されています。それは組織化されています。 InnoDBでは、Clusteredとも定義されています。他のベンダーは、さまざまな組み合わせクラスタリング、非BTreeインデックス作成などを許可しています。MySQLは、制限が「​​ほとんどの人」にとって「十分な」ものであると判断しました。

「最悪の」省略は徐々に修正されています。トランザクションは、おそらく最も重要で最も重要です。それは2001年に到着した(?)、MyISAMは今年(2016年)8.0の出現で削除されている。

4.1(2002?)サブクエリを見た。その前に、tmpテーブルの作成は「十分に良い」ものでした。現在(8.0)のサブクエリは、CTEによってワンワップされています。これは、tmpテーブルもサブクエリも効率的に実行できないいくつかの項目をカバーしています。

MySQL 5.6および5.7とMariaDB 10.xには膨大な数の最適化が行われています。あなたはおそらくそれらのカップル以上を使用していないでしょう。製品は「リターンを減らす」ものです。それは、次の数千の非常にまれな最適化をチェックするためにオプティマイザの速度を落とすと、「リーンで平均的」な遺産を損なうでしょう。

一方、私のような人たちは、「MySQL/MariaDBにはこれがないので、回避策があります」と多くの時間を費やしています。あなたのケースでは、それはより短いCOUNT(*)です。清潔な回避策があるため、提案が実装されるまでにはさらに10年かかる場合があります。 bugs.mysql.comまたはmariadb.comでバグレポートを提出して、最適化を提案することはOKです。

ORDER BY a ASC, b DESCを最適化する方法として、INDEX(a ASC, b DESC)がほとんど必要ありません。それは8.0と来ている。しかし、5,000件以上の質問が本当に必要な場合は疑問です。 (私は多くのクエリを見てきました。)私はその希少性がなぜそれを実装するのに20年かかったのかということです。きれいな回避策の欠如は、なぜ10年もかからなかった理由です。

関連する問題