0

SQL の最適化に関する多くのコメントを見てきましたが、答えが見つかりません。

私のアプリはこのSQLを使用しています...

SELECT * FROM ((
  SELECT DISTINCT 
      c.companyname,
      c.tradingas,
      a.quarantined,
      c.companyid,
      a.address1,
      a.city,
      a.postcode,
      a.region,
      c.origin_dsn,
      d.title,
      d.firstname,
      d.surname,
      d.position,
      a.telephoneno,
      a.companyemail,
      addresstypes,
      markets 
    FROM companies c
    join addresses a on c.companyid = a.companyid
    join contacts d on c.companyid = d.companyid
    where d.origin_dsn = 'ifd'
      and primarycontact = 1
      and d.clientid = 0
      and c.origin_dsn = 'ifd' and
      a.origin_dsn = 'ifd' and
      c.companyid in (
        select distinct companyid
        from products
        where description IN ('Windows and Doors','Vertical Sliders','Bi-Fold Doors')
          AND type IN ('wd:f','wd:b')
          AND material = 'PVCu'
          AND origin_dsn = 'ifd'
  ))
  UNION (
    SELECT DISTINCT
      c.companyname,
      c.tradingas,
      a.quarantined,
      c.companyid,
      a.address1,
      a.city,
      a.postcode,
      a.region,
      c.origin_dsn,
      d.title,
      d.firstname,
      d.surname,
      d.position,
      a.telephoneno,
      a.companyemail,
      addresstypes,
      markets
    FROM companies c
    join addresses a on c.companyid = a.companyid
    join contacts d on c.companyid = d.companyid
    where d.origin_dsn = 'ifd'
      and primarycontact = 1
      and d.clientid = 0
      and c.origin_dsn = 'ifd'
      and a.origin_dsn = 'ifd'
      and c.companyid in (
        select distinct companyid
        from products
        where type IN ('cr:f','cr:b')
          AND origin_dsn = 'ifd')
      )
  ) as t
  where t.quarantined = 0
    and t.origin_dsn = 'ifd'
    and t.region IN (
      'Northern Counties','North West','Yorkshire',
      'East Midlands','West Midlands','South West',
      'Home Counties','Southern Counties','Greater London',
      'Scotland','Wales','Northern Ireland')
  order by companyname

mysqlクエリブラウザで実行するのに3.5秒という驚異的な時間がかかります(低速で低スペックのラップトップで)

このクエリは、それぞれ約 1.5 秒かかる 2 つの非常によく似たクエリで構成されています。

私のアプリでは、最大 4 つの類似の共用体が必要になる可能性があります。

より効率的に書く方法を誰かが提案できますか?

4

1 に答える 1

0

私はあなたの会社の製品基準を最初に事前クエリに移動します...その後、参加して他の詳細を取得します...したがって、会社IDは事前に一度だけ選択されます。プレクエリ、ここでサンプリングしたように、複数の基準を結合することができます...

where 
      ( first set of criteria )
   OR ( second set of criteria )
   OR ( third set of criteria )

(ただし、両方の基準で origin_dsn = 'ifd' が使用されていますが、これは単純化される可能性がありますが、基準が実際にどのように構築されているかはわかりません)。

クエリを最適化するために、 Products テーブルで (Origin_DSN, type, material )のインデックスを確保します。

アドレス テーブルの場合、( companyid、origin_dsn、quarantined、region ) のインデックス

連絡先テーブルのインデックス ( companyid, origin_dsn, clientid )

何かのようなもの...

SELECT DISTINCT 
      c.companyname,
      c.tradingas,
      a.quarantined,
      c.companyid,
      a.address1,
      a.city,
      a.postcode,
      a.region,
      c.origin_dsn,
      d.title,
      d.firstname,
      d.surname,
      d.position,
      a.telephoneno,
      a.companyemail,
      addresstypes,
      markets 
   FROM 
      ( select distinct 
              p.companyid
           from 
              products p
           where 
                 (     p.origin_dsn = 'ifd' 
                   AND p.`type` IN ('cr:f','cr:b') )
              OR (     p.origin_dsn = 'ifd' 
                   AND p.`type` IN ('wd:f','wd:b')
                   AND p.material = 'PVCu' 
                   AND p.description IN ('Windows and Doors','Vertical Sliders','Bi-Fold Doors') ) ) as PreQuery

         JOIN companies c
            ON PreQuery.CompanyID = c.CompanyID


            join addresses a 
               on c.companyid = a.companyid
              and c.origin_dsn = a.origin_dsn 
              and a.quarantined = 0
              and a.Region in ( 'Northern Counties',
                                'North West',
                                'Yorkshire',
                                'East Midlands',
                                'West Midlands',
                                'South West',
                                'Home Counties',
                                'Southern Counties',
                                'Greater London',
                                'Scotland',
                                'Wales',
                                'Northern Ireland' )
            join contacts d 
               on c.companyid = d.companyid
              AND c.origin_dsn = d.origin_dsn 
              and d.clientid = 0
   where 
          primarycontact = 1
      and c.origin_dsn = 'ifd' 
   order by 
      c.companyname
于 2013-05-23T16:53:16.683 に答える