1

次のテーブルを含む DB があります。

  • 従業員
  • 会社
  • lt_employee_title

従業員は複数の役職を持つことができ、企業は複数の従業員を持つことができます。

lt_employee_titleテーブルとテーブルを検索して、テーブルからcompany取得しようとしています。employee_idemployee

テーブル構造:

CREATE TABLE `employee` (
  `employee_id` int(11) NOT NULL AUTO_INCREMENT,
  `company_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`employee_id`),
  KEY `employee_id` (`company_id`)
) ENGINE=InnoDB;

CREATE TABLE `company` (
  `company_id` int(11) NOT NULL AUTO_INCREMENT,
  `URL` varchar(100) DEFAULT NULL,
  `company_name` varchar(100) DEFAULT NULL,
  `date_created` date DEFAULT NULL,
  `date_updated` datetime DEFAULT NULL,
  `address1` varchar(45) DEFAULT NULL,
  `address2` varchar(45) DEFAULT NULL,
  `phone` varchar(20) DEFAULT NULL,
  `phone2` varchar(20) DEFAULT NULL,
  `fax` varchar(20) DEFAULT NULL,
  `city` varchar(45) DEFAULT NULL,
  `major_city_id` int(11) DEFAULT NULL,
  `region_code` varchar(10) DEFAULT NULL,
  `zip` varchar(15) DEFAULT NULL,
  `country_code` varchar(2) DEFAULT NULL,
  `archived` tinyint(4) NOT NULL DEFAULT '0',
  `enabled` enum('yes','no') DEFAULT 'yes',
  PRIMARY KEY (`company_id`),
  KEY `country_code` (`country_code`),
  KEY `employee` (`number_of_employees_id`),
  KEY `phone` (`phone`(3)),
  KEY `state` (`region_code`),
  KEY `archived` (`archived`)
) ENGINE=InnoDB;

CREATE TABLE `lt_employee_title` (
  `employee_id` int(11) NOT NULL,
  `title_id` int(11) NOT NULL,
  UNIQUE KEY `unique_field` (`employee_id`,`title_id`),
  KEY `employee_id` (`employee_id`),
  KEY `title_id` (`title_id`),
  KEY `both` (`title_id`,`employee_id`),
  KEY `both2` (`employee_id`,`title_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8$$;

 

このクエリは高速です。

SELECT SQL_NO_CACHE
  *

FROM lt_employee_title AS let

JOIN employee AS ee
  ON ee.employee_id = let.employee_id

JOIN company AS com
  ON com.company_id = ee.company_id


WHERE let.title_id = 9
  AND com.region_code IN('AL', 'AK', 'AZ')
  AND com.archived = 0


LIMIT 125;

 

しかし、これらはそうではありません:

SELECT SQL_NO_CACHE
  COUNT(*)

FROM lt_employee_title AS let
...

 

SELECT SQL_NO_CACHE SQL_CALC_FOUND_ROWS
  *

FROM lt_employee_title AS let
...

 

任意のタイプのカウントを追加する違いにより、時間が 0.016 秒から 4.0 秒に移動します。約 250,000 件のタイトル、900,000 件の企業エントリ、および 100 万人を超える従業員レコードがありますが、今後も増えていく予定です。

count()orSQL_CALC_FOUND_ROWSまたはを追加するとORDER BY com.number_of_employees_id、EXPLAIN は一時テーブルと file_sort を使用しているため、速度が低下します。このSQLをより効率的に実行する方法はありますか?

「SQL_CALC_FOUND_ROWS」で説明する

1   SIMPLE  company ref PRIMARY,state,created,updated,employee_number,archived  state   33  const   210864  Using where; Using filesort
1   SIMPLE  employee    ref PRIMARY,employee_id,created,updated employee_id 5   lead411_main.company.company_id 1   Using where; Using index
1   SIMPLE  lt_employee_title   eq_ref  unique_field,employee_id,title_id,both,both2    unique_field    8   lead411_main.employee.employee_id,const 1   Using index

EXPLAIN WITH OUT "SQL_CALC_FOUND_ROWS"

1   SIMPLE  company index   PRIMARY,state,created,updated,employee_number,archived  employee    5       986 Using where  
1   SIMPLE  employee    ref PRIMARY,employee_id,created,updated employee_id 5   lead411_main.company.company_id 1   Using where; Using index  
1   SIMPLE  lt_employee_title   eq_ref  unique_field,employee_id,title_id,both,both2    unique_field    8   lead411_main.employee.employee_id,const 1   Using index  
4

0 に答える 0