简体   繁体   中英

How to optimize a MYSQL Query?

Schema 基本架构

I am trying to write a query that fetch the latest stats of shift working at a factory but myquery becomes so complex that it took almost 12 seconds to execute in mysql workbench.Any suggestions to optimize my query ?

SELECT c_time, 
      shift 
INTO  @c_time, 
      @shift 
FROM roll_header_view 
WHERE id = 'id';

SELECT f.*,
employee.name as employee_name, 
employee.employee_code as employee_code 
FROM roll_header_view f 
LEFT OUTER JOIN employee_view employee 
    ON employee.id = f.employee_id 
WHERE c_time <= @c_time 
AND c_time > 
        (SELECT IFNULL(max(c_time), 0) 
        FROM roll_header_view 
        WHERE shift != @shift 
        AND c_time <= @c_time); 

'CREATE TABLE `employee` (
  `id` bigint(20) NOT NULL DEFAULT ''0'',
  `mac_id` int(11) NOT NULL DEFAULT ''100'',
  `c_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `u_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `c_by` varchar(100) NOT NULL DEFAULT ''100'',
  `u_by` varchar(100) NOT NULL DEFAULT ''100'',
  `isactive` varchar(1) NOT NULL DEFAULT ''Y'',
  `employee_code` varchar(100) NOT NULL DEFAULT '''',
  `name` varchar(100) NOT NULL DEFAULT '''',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1'



'CREATE TABLE `roll_header` (
  `id` bigint(20) NOT NULL DEFAULT ''0'',
  `mac_id` int(11) NOT NULL DEFAULT ''100'',
  `c_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `u_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `c_by` varchar(100) NOT NULL DEFAULT ''100'',
  `u_by` varchar(100) NOT NULL DEFAULT ''100'',
  `isactive` varchar(1) NOT NULL DEFAULT ''Y'',
  `roll_no` bigint(20) NOT NULL DEFAULT ''0'',
  `actual_id` bigint(20) NOT NULL DEFAULT ''0'',
  `req_cuttable_width` float NOT NULL DEFAULT ''0'',
  `act_cuttable_width` float NOT NULL DEFAULT ''0'',
  `color` varchar(100) NOT NULL DEFAULT '''',
  `contract_no` varchar(100) NOT NULL DEFAULT '''',
  `construction` varchar(100) NOT NULL DEFAULT '''',
  `finish` varchar(100) NOT NULL DEFAULT '''',
  `meter_yard_length` float NOT NULL DEFAULT ''0'',
  `meter` float NOT NULL DEFAULT ''0'',
  `yard` float NOT NULL DEFAULT ''0'',
  `is_meter_yard` varchar(1) NOT NULL DEFAULT ''Y'',
  `total_l_point` int(11) NOT NULL DEFAULT ''0'',
  `penalty_point` float NOT NULL DEFAULT ''0'',
  `trolly_no` varchar(100) NOT NULL DEFAULT '''',
  `description` varchar(1000) NOT NULL DEFAULT '''',
  `shift` varchar(100) NOT NULL DEFAULT '''',
  `shift_end` varchar(1) NOT NULL DEFAULT ''0'',
  `shift_start` varchar(1) NOT NULL DEFAULT ''0'',
  `quality` varchar(100) NOT NULL DEFAULT ''A'',
  `employee_id` bigint(20) NOT NULL DEFAULT ''1'',


  PRIMARY KEY (`id`),
  KEY `fk_roll_header_employee_id` (`employee_id`),
  CONSTRAINT `roll_header_ibfk_1` FOREIGN KEY (`employee_id`) REFERENCES `employee` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1'

I have shared all the relevant data for this query ie table structure ER diagram Explain etc kindly help me optimizing this query in a better and performance oriented way Explain plan

解释计划

I've tried to figure out what your query is supposed to do - I'm sure there's a better way to write it, but it makes very little sense to me.

I've converted it to a SQL Fiddle, here: http://sqlfiddle.com/#!9/5435e2/6

The problem is that your subquery

(SELECT IFNULL(max(c_time), 0) 
        FROM roll_header_view 
        WHERE shift != @shift 
        AND c_time <= @c_time);

is being executed for every row it compares, and cannot use an index. If you re-write the query as follows, that problem goes away.

SELECT c_time, 
      shift 
INTO  @c_time, 
      @shift 
FROM roll_header
WHERE id = 'id';

SELECT @max_time = IFNULL(max(c_time), 0) 
        FROM roll_header
        WHERE shift != @shift 
        AND c_time <= @c_time;

SELECT f.*,
employee.name as employee_name, 
employee.employee_code as employee_code 
FROM roll_header f 
LEFT OUTER JOIN employee employee 
    ON employee.id = f.employee_id 
WHERE f.c_time <= @c_time 
AND f.c_time > 
        @max_time; 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM