30 분마다 통계 테이블을 업데이트하는 cron을 통해 PHP 스크립트에서 다소 복잡한 SQL 쿼리를 실행하고 있습니다.복잡한 MySQL 쿼리가 가끔씩 실행되지 않습니다.
일반적으로 업데이트가 작동하며 약 40.000 개의 레코드가 약 2-3 분 동안 처리됩니다. Ocassionally이 쿼리는 아무런 결과없이 몇 시간까지 무한히 길게 실행됩니다. PHPMyAdmin에서 MySQL 프로세스를 열면 50.000 초 이상의 시간이 표시된 쿼리가 표시됩니다.
이로 인해 하루 종일 더 이상 테이블이 업데이트되지 않는 문제가 발생합니다. 왜 그런 일이 일어나는거야?
쿼리는 복잡하지만 비 특별 :
SELECT `a`.`id`
AS
`id`,
`a`.`debitor`
AS `debitor`,
`a`.`wnummer`
AS `wnummer`,
`a`.`konto`
AS `konto`,
`a`.`datum`
AS `datum`,
`a`.`name`
AS `name`,
`a`.`name2`
AS `name2`,
`a`.`land`
AS `land`,
`a`.`plz`
AS `plz`,
`a`.`ort`
AS `ort`,
`a`.`str`
AS `str`,
`a`.`beschichterdatum`
AS `beschichterdatum`,
`a`.`werkstattdatum`
AS `werkstattdatum`,
`a`.`plandatum`
AS `plandatum`,
`a`.`kommision`
AS `kommision`,
`a`.`status`
AS `status`,
(SELECT `protokoll`.`ts`
FROM `protokoll`
WHERE (`protokoll`.`auftrag_id` = `a`.`id`)
AND (`protokoll`.`status_neu` = `a`.`status`)
ORDER BY `protokoll`.`ts` DESC
LIMIT 1)
AS `status_ts`,
`a`.`tourname`
AS `tourname`,
`a`.`anlage`
AS `anlage`,
`a`.`user`
AS `user`,
`a`.`vertreter`
AS `vertreter`,
`a`.`druckmodus`
AS `druckmodus`,
(SELECT GROUP_CONCAT(DISTINCT `position`.`maschine` ORDER BY
`position`.`maschine` ASC SEPARATOR ', ') AS
`maschine`
FROM `position`
WHERE (`position`.`auftrag_id` = `a`.`id`)
AND (`position`.`status` = 20)
AND (Length(`position`.`maschine`) > 0))
AS
`maschine`,
(SELECT GROUP_CONCAT(DISTINCT `position`.`beschichter` ORDER
BY
`position`.`beschichter` ASC SEPARATOR ', ') AS
`beschichter`
FROM `position`
WHERE (`position`.`auftrag_id` = `a`.`id`)
AND (`position`.`status` = 50)
AND (Length(`position`.`beschichter`) > 0))
AS
`beschichter`,
(SELECT DISTINCT `position`.`rueckstandinfo` AS
`rueckstandinfo`
FROM `position`
WHERE (`position`.`auftrag_id` = `a`.`id`)
ORDER BY IF((Length(`position`.`rueckstandinfo`) > 0), 1,
0) DESC
,
COUNT(*) DESC
LIMIT 1)
AS `rueckstandinfo`,
(SELECT COUNT(*)
FROM `position`
WHERE (`position`.`auftrag_id` = `a`.`id`))
AS `menge`,
(SELECT COUNT(*)
FROM `position`
WHERE (`position`.`auftrag_id` = `a`.`id`)
AND (`position`.`schrott` = 1))
AS `schrott`,
(SELECT SUM(`position`.`menge` -
`position`.`schrott`)
FROM `position`
WHERE ((`position`.`auftrag_id` = `a`.`id`)
AND ((CASE
WHEN (`position`.`status` < 41) THEN (
To_days(`a`.`werkstattdatum`) - To_days(NOW()))
WHEN (`position`.`status` < 66) THEN (
To_days(`a`.`beschichterdatum`) - To_days(NOW()))
WHEN (`position`.`status` < 100) THEN (
To_days(`a`.`plandatum`) - To_days(NOW()))
END) < 0)))
AS `rueckstaendig`,
(CASE
WHEN (`a`.`status` < 41) THEN (To_days(`a`.`werkstattdatum`) -
To_days(NOW()))
WHEN (`a`.`status` < 66) THEN (
To_days(`a`.`beschichterdatum`) - To_days(
NOW()))
WHEN (`a`.`status` < 100) THEN (
To_days(`a`.`plandatum`) - To_days(NOW())
)
END)
AS `kalendertage`
FROM `auftrag` `a`
표가의 MyISAM 엔진을 가지고있다.
EXPLAIN 출력 :
스키마 auftrag :
CREATE TABLE `auftrag`
(
`id` INT(11) NOT NULL AUTO_INCREMENT COMMENT 'Auftrag',
`debitor` VARCHAR(255) DEFAULT NULL COMMENT 'Kunde',
`wnummer` VARCHAR(255) DEFAULT NULL COMMENT 'W-Nr.',
`konto` VARCHAR(255) DEFAULT NULL COMMENT 'Konto',
`vertreter` INT(11) NOT NULL DEFAULT '0' COMMENT 'Vertreter',
`preisliste` INT(11) NOT NULL DEFAULT '0' COMMENT 'Preisliste',
`datum` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00'
COMMENT
'Auftragseingang',
`name` VARCHAR(255) DEFAULT NULL COMMENT 'Name',
`name2` VARCHAR(255) DEFAULT NULL COMMENT 'Name 2',
`land` VARCHAR(255) DEFAULT NULL COMMENT 'Land',
`plz` VARCHAR(255) DEFAULT NULL COMMENT 'PLZ',
`ort` VARCHAR(255) DEFAULT NULL COMMENT 'Ort',
`str` VARCHAR(255) DEFAULT NULL COMMENT 'Strasse',
`str2` VARCHAR(255) DEFAULT NULL COMMENT 'Strasse 2',
`beschichterdatum` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00'
COMMENT
'Beschichtung',
`werkstattdatum` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00'
COMMENT
'Werkstatt',
`plandatum` DATE NOT NULL DEFAULT '0000-00-00' COMMENT 'Versand',
`kiste` INT(1) NOT NULL DEFAULT '0' COMMENT
'Anzahl Schleifkisten',
`anlage` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00'
COMMENT
'Auftragsanlage',
`user` INT(11) NOT NULL DEFAULT '0' COMMENT 'Benutzer',
`menge_sofortschrott` INT(11) NOT NULL DEFAULT '0',
`menge_gesamt` INT(11) NOT NULL DEFAULT '0' COMMENT
'Menge Lieferschein',
`menge_realvomkunden` INT(11) NOT NULL DEFAULT '0' COMMENT 'Menge erhalten'
,
`menge_beschrift` INT(11) NOT NULL DEFAULT '0' COMMENT
'Menge Beschriftung',
`bemerkung` TEXT COMMENT 'Bemerkung',
`rueckstandinfo` VARCHAR(255) DEFAULT NULL COMMENT 'Info Rueckstand',
`bem_c206` TEXT,
`bem_c207` TEXT,
`bem_c208` TEXT,
`bem_c209` TEXT,
`kommision` VARCHAR(255) DEFAULT NULL COMMENT 'Kommission',
`status` INT(11) NOT NULL DEFAULT '0' COMMENT 'Status Auftrag'
,
`belegart` VARCHAR(255) NOT NULL DEFAULT 'Auftrag' COMMENT
'Belegart',
`emailapkd` VARCHAR(255) DEFAULT NULL COMMENT
'eMail Arbeitsplan Kunde',
`emailapvt` VARCHAR(255) DEFAULT NULL COMMENT
'eMail Arbeitsplan Vertreter',
`rech_name1` VARCHAR(255) DEFAULT NULL COMMENT 'Rechnung Name',
`rech_name2` VARCHAR(255) DEFAULT NULL COMMENT 'Rechnung Name 2',
`rech_land` VARCHAR(255) DEFAULT NULL COMMENT 'Rechnung Land',
`rech_plz` VARCHAR(255) DEFAULT NULL COMMENT 'Rechnung PLZ',
`rech_ort` VARCHAR(255) DEFAULT NULL COMMENT 'Rechnung Ort',
`rech_str` VARCHAR(255) DEFAULT NULL COMMENT 'Rechnung Strasse',
`rech_str2` VARCHAR(255) DEFAULT NULL COMMENT
'Rechnung Strasse 2',
`gesendet_an` TEXT COMMENT 'Arbeitsplan gesendet',
`angebotmail` DATETIME DEFAULT NULL COMMENT 'Angebot Intern',
`requestangebot` SMALLINT(1) NOT NULL DEFAULT '0' COMMENT
'Angebot',
`gutschein` CHAR(1) NOT NULL DEFAULT 'N' COMMENT 'Gutschein',
`tourname` VARCHAR(255) DEFAULT NULL COMMENT 'Tourenname Pickup'
,
`druckmodus` VARCHAR(255) NOT NULL DEFAULT '5/12/""/DL/""'
COMMENT
'Schl,Beschicht,Teillief,DL-ZS',
`fremdkonto` VARCHAR(255) DEFAULT NULL COMMENT 'Fremdkonto',
`versandart` VARCHAR(255) NOT NULL DEFAULT '9' COMMENT
'Versandart',
`c201` VARCHAR(255) DEFAULT NULL,
`ansprechpartner` VARCHAR(255) DEFAULT NULL COMMENT 'AP',
PRIMARY KEY (`id`),
KEY `status` (`status`),
KEY `tourname` (`tourname`),
KEY `wnummer` (`wnummer`),
KEY `debitor` (`debitor`),
KEY `user` (`user`)
)
ENGINE=myisam
AUTO_INCREMENT=91809
DEFAULT CHARSET=utf8
스키마 총수 :
CREATE TABLE `position`
(
`id` INT(11) NOT NULL AUTO_INCREMENT COMMENT 'Position',
`auftrag_id` INT(11) NOT NULL DEFAULT '0' COMMENT 'Auftrag',
`artikel_id` VARCHAR(30) NOT NULL COMMENT 'Artikel',
`menge` DECIMAL(6, 0) NOT NULL DEFAULT '0' COMMENT 'Menge',
`listpreis` DECIMAL(10, 2) NOT NULL DEFAULT '0.00' COMMENT
'Listenpreis',
`rabatt` DECIMAL(6, 2) NOT NULL DEFAULT '0.00' COMMENT
'Rabatt Prozent',
`preis` DECIMAL(13, 2) NOT NULL DEFAULT '0.00' COMMENT 'Preis',
`wl_rab` DECIMAL(6, 2) DEFAULT NULL COMMENT 'Rabatt',
`wl_preis` DECIMAL(13, 2) DEFAULT NULL COMMENT 'Preis',
`schrott` DECIMAL(6, 0) NOT NULL DEFAULT '0' COMMENT 'Schrott',
`maschine` VARCHAR(5) DEFAULT NULL COMMENT 'Maschine',
`beschichter` VARCHAR(5) DEFAULT NULL COMMENT 'Beschichter',
`beschichtung` VARCHAR(30) DEFAULT NULL COMMENT 'Beschichtung',
`sk_kond` VARCHAR(2) DEFAULT NULL COMMENT 'Schneidkanten NB/VB',
`status` SMALLINT(6) NOT NULL DEFAULT '15' COMMENT 'Status',
`infotext` TEXT COMMENT 'Infotext',
`artikeltext` TEXT COMMENT 'Artikeltext',
`schleiftext` TEXT COMMENT 'Schleifanweisung',
`name_en` VARCHAR(255) DEFAULT NULL COMMENT 'Artikeltext EN',
`name_it` VARCHAR(255) DEFAULT NULL COMMENT 'Artikeltext IT',
`name_fr` VARCHAR(255) DEFAULT NULL COMMENT 'Artikeltext FR',
`c214` VARCHAR(200) DEFAULT NULL,
`enddatum` DATETIME DEFAULT NULL,
`reklamation` CHAR(1) NOT NULL DEFAULT 'N' COMMENT 'Reklamation',
`werkzeugtyp` ENUM('Standard', 'LohntNichtInfo', 'Sonderwerkzeug',
'Kundenwerkzeug') NOT NULL DEFAULT 'Standard' COMMENT 'Werkzeugtyp',
`durchmesser` VARCHAR(50) DEFAULT NULL COMMENT 'Durchmesser',
`rueckstandinfo` VARCHAR(255) DEFAULT NULL COMMENT 'Rueckstandinfo',
PRIMARY KEY (`id`),
KEY `status` (`status`),
KEY `auftrag_id` (`auftrag_id`),
KEY `artikel_id` (`artikel_id`),
KEY `maschine` (`maschine`),
KEY `beschichter` (`beschichter`),
KEY `rueckstandinfo` (`rueckstandinfo`),
KEY `enddatum` (`enddatum`)
)
ENGINE=myisam
AUTO_INCREMENT=2518917
DEFAULT CHARSET=utf8
,617,
스키마 protokoll는 :
CREATE TABLE `protokoll`
(
`id` INT(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`usr_id` INT(11) NOT NULL COMMENT 'Benutzer',
`auftrag_id` INT(11) NOT NULL COMMENT 'Auftrag',
`pos_id` INT(11) NOT NULL COMMENT 'Position',
`artikel_id` VARCHAR(255) NOT NULL COMMENT 'Artikel',
`status_alt` SMALLINT(6) DEFAULT NULL COMMENT 'Status ALT',
`status_neu` SMALLINT(6) DEFAULT NULL COMMENT 'status NEU',
`info` VARCHAR(255) DEFAULT NULL COMMENT 'Infotext',
`ts` DATETIME NOT NULL COMMENT 'Zeitstempel',
PRIMARY KEY (`id`),
KEY `ts` (`ts`),
KEY `auftrag_id_2` (`auftrag_id`, `artikel_id`, `status_neu`)
)
ENGINE=myisam
AUTO_INCREMENT=361183
DEFAULT CHARSET=utf8
아마도 동일한 필드에서 as 절을 사용하지 않으면 선을 절반으로 줄일 수 있습니다. 스키마를 공유 할 수 있습니까? – rwilliams
중요 할 수있는 또 다른 부가 정보 : 쿼리는이 쿼리의 결과를 선택한 필드와 동일한 구성표를 갖고 있지만 자체 인덱스가있는 단일 테이블에 삽입하는 INSERT 문에 캡슐화됩니다. 무한한 실행은 삽입/색인 작성 중에 발생합니다. – proximus