web-dev-qa-db-ja.com

一時を使用して削除する方法?

「一時的な使用」を削除してください。私は多くの異なるオプションを試しましたが、取り除くことは不可能です。または、ソートが消えるか、「一時使用中」と表示されます。 ;(

カテゴリテーブル:

 `product_category_multi` (
      `m_Id` mediumint(7) NOT NULL,
      `prod_Id` smallint(6) unsigned NOT NULL,
      `multi_cat` mediumint(7) unsigned NOT NULL
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8;

インデックステーブル:

ALTER TABLE `product_category_multi`
  ADD PRIMARY KEY (`m_Id`),
  ADD KEY `multi_cat` (`multi_cat`),
  ADD KEY `Id` (`prod_Id`);

コンテンツテーブルの例:

m_Id    prod_Id     multi_cat
-------+-----------+---------+  
1       1           5
2       1           1
3       1           6
4       2           5
5       2           1
6       3           5
7       4           5
8       4           6

製品表:

`shop_product` (
  `Id` int(10) unsigned NOT NULL,
  `product_article` varchar(20) NOT NULL,
  `product_article_main` varchar(20) NOT NULL,
  `product_category` int(10) unsigned NOT NULL DEFAULT '0',
  `product_name` varchar(255) NOT NULL,
  `product_price` int(10) unsigned NOT NULL DEFAULT '0',
  `product_active` smallint(1) unsigned NOT NULL DEFAULT '0',
  `product_warehouse_temp` enum('0','1') NOT NULL,
  `product_top` enum('0','1') NOT NULL,
) ENGINE=MyISAM DEFAULT CHARSET=utf8 PACK_KEYS=0;

インデックステーブル:

ALTER TABLE `shop_product`
  ADD PRIMARY KEY (`Id`),
  ADD KEY `product_name` (`product_name`),
  ADD KEY `product_price` (`product_price`),
  ADD KEY `product_article_main` (`product_article_main`);

コンテンツテーブルの例:

Id  product_article     product_article_main    product_category    product_name    product_price   product_active  product_warehouse_temp  product_top         
--+-------------------+------------------------+------------------+---------------+----------------+--------------+------------------------+------------+
1   qwe                 qwe                     5                   name1           20              1               1                       0
2   asd                 qwe                     5                   name2           30              1               1                       0
3   zxc                 qwe                     5                   name3           50              1               0                       1
4   wer                 sdf                     6                   name4           10              1               1                       0
5   sdf                 sdf                     6                   name5           20              1               1                       0
6   xcv                 sdf                     6                   name6           50              1               1                       0
7   ert                 cvb                     1                   name7           10              1               0                       1
8   cvb                 cvb                     1                   name8           20              1               1                       0

リクエスト:

SELECT
    A.*
FROM
(
    SELECT prod.Id
    FROM shop_product prod
    INNER JOIN (
            SELECT prod_Id
            FROM product_category_multi
            WHERE multi_cat = '5'
        ) AS cat ON cat.prod_Id = prod.Id

    WHERE 
        prod.product_active = '1' 
        AND prod.product_published_start <= 1471376797
        AND prod.product_price = (
            select MIN(temp.product_price)
            from shop_product temp 
            where prod.product_article_main=temp.product_article_main 
        )   
    ORDER BY prod.product_warehouse_temp DESC, prod.product_top DESC, prod.product_review DESC, prod.Id ASC
    LIMIT 0, 20
) B 
INNER JOIN shop_product A USING (Id)

行0〜19を表示しています(合計20、クエリに0.0899秒かかりました)。

説明:

id  select_type     table                   type        possible_keys           key                     key_len     ref                             rows    Extra
--+---------------+------------------------+-----------+----------------------+-----------------------+-----------+-------------------------------+--------+-------------
1   PRIMARY         <derived2>              ALL         NULL                    NULL                    NULL        NULL                            20      
1   PRIMARY         A                       eq_ref      PRIMARY                 PRIMARY                 4           B.Id                            1           
2   DERIVED         product_category_multi  ref         multi_cat,Id            multi_cat               3           const                           6869    Using temporary; Using filesort
2   DERIVED         prod                    eq_ref      PRIMARY                 PRIMARY                 4           product_category_multi.prod_Id  1       Using index condition; Using where
4   DEP. SUBQUERY   temp                    ref         product_article_main    product_article_main    62          prod.product_article_main       3

これはこのバリアントでしたが、「ORDER BY」句では機能しません

        SELECT B.*
            FROM(
                SELECT prod_Id
                FROM product_category_multi
                WHERE multi_cat = '5'
            ) cat

            INNER JOIN (
                SELECT 
                    prod.Id
                FROM shop_product prod
                WHERE 
                    prod.product_price = (
                        select MIN(temp.product_price)
                        from shop_product temp 
                        where prod.product_article_main=temp.product_article_main 
                    )
                    AND prod.product_active = '1' 
                    AND prod.product_published_start <= '1471268208'
                ORDER BY 
                    prod.product_warehouse_temp DESC, prod.product_top DESC
            ) prod ON cat.prod_Id = prod.id


        INNER JOIN shop_product B USING (Id)

行0〜24を表示しています(合計2296、クエリにかかった時間は0.0046秒です)。

1
klerol

Tempテーブルとfilesortは悪ではありません。それらは不十分なインデックスを暗示する症状です。

JOINが機能する場合はサブクエリを使用しないでください。

_SELECT prod.Id
FROM shop_product prod
INNER JOIN (
        SELECT prod_Id
        FROM product_category_multi
        WHERE multi_cat = '5'
    ) AS cat ON cat.prod_Id = prod.Id
_

->

_SELECT prod.Id
FROM shop_product prod
INNER JOIN product_category_multi cat
    ON cat.prod_Id = prod.Id
WHERE  multi_cat = '5'
_

一方、集計(MIN(temp.product_price))を使用したサブクエリは、おそらくそれよりも優れています。

_ORDER BY a DESC, b ASC_は最適化できません。すべてASCまたはDESCである必要があります。あなたの場合、idを注文する方法はおそらく問題ではないので、DESCに変更します。 (ここでの最適化を妨げる他の問題があるかもしれませんが、これは始まりです。)このインデックスmightヘルプ:INDEX(product_warehouse_temp, product_top, product_review, Id)

_product_category_multi_が多対多のマッピングテーブルである場合、いくつかの理由で非効率的です。 ここ がより良い方法であり、それがより良い理由がたくさん含まれています。

有用な場合は「複合」インデックスを使用します。KEY multi_cat(multi_cat)を_(multi_cat, prod_id)_に置き換えます。 KEY product_article_main (product_article_main)を_(product_article_main, product_price)_に置き換えます

長い目で見れば、InnoDBはMyISAMよりも優れたエンジンですが、現時点ではそれについては触れません。クエリの高速化はrealの質問だと思います。

質問に戻りましょう...このクエリに必要な「一時」テーブルの数は不明です。 (_EXPLAIN FORMAT=JSON SELECT ..._と表示されます。)私の推奨インデックスmayは一時テーブルの一部を削除し、おそらくクエリを高速化します。

4
Rick James