簡體   English   中英

在where子句之間的datetime時,MySQL查詢變慢

[英]Slow MySQL query when datetime between in where clause

我有一張表格進行患者滿意度調查(在底部創建聲明),其中包含17個問題和一些文本塊。 將調查輸入數據庫后,它將設置日期時間字段。 我必須能夠平均運行時間段(周/月/年)的報告。 目前,我每周進行一次查詢。

我的查詢最多需要16秒才能運行,並且在運行期間最多占用CPU。 然后,我必須這樣做查詢13個星期獲得全球平均水平,那么我做每查詢選擇醫生14次以上 (可以是22倍介於0)。

我嘗試使用WHERE date >= 'date low' AND date <= 'date high'WHERE date BETWEEN 'date low' AND 'date high' ,並且我嘗試了CAST('date' as datetime)無效。 在對查詢進行性能分析時,它似乎將大量時間都花在了statisticsEXPLAIN似乎是在說它沒有使用datescanned索引,但是我不知道為什么。

當前大約有1000行,但是當行數只有一半時查詢運行良好。 由此,我發現無論如何創建表還是如何形成查詢都存在一個非常糟糕的問題。

注:在具有4GB內存和1個虛擬proc的VMWare ESXi 5.1上的Debian 7.2上運行

創建表:

CREATE TABLE IF NOT EXISTS `survey` (
   `id` int(10) NOT NULL AUTO_INCREMENT,
   `datescanned` datetime NOT NULL,
   `physician_fk` int(5) NOT NULL,
   `procedure` varchar(255) DEFAULT NULL,
   `gender` varchar(12) NOT NULL,
   `patientage` varchar(50) NOT NULL DEFAULT 'Not marked',
   `question01_fk` int(1) NOT NULL,
   `question02_fk` int(1) NOT NULL,
   `question03_fk` int(1) NOT NULL,
   `question04_fk` int(1) NOT NULL,
   `question05_fk` int(1) NOT NULL,
   `question06_fk` int(1) NOT NULL,
   `question07_fk` int(1) NOT NULL,
   `question08_fk` int(1) NOT NULL,
   `question09_fk` int(1) NOT NULL,
   `question10_fk` int(1) NOT NULL,
   `question11_fk` int(1) NOT NULL,
   `question12_fk` int(1) NOT NULL,
   `question13_fk` int(1) NOT NULL,
   `question14_fk` int(1) NOT NULL,
   `question15_fk` int(1) NOT NULL,
   `question16_fk` int(1) NOT NULL,
   `question17_fk` int(1) NOT NULL,
   `notes` text,
   `email` varchar(256) DEFAULT NULL,
   `name` varchar(256) DEFAULT NULL,
   `qanotes` text,
   `referredby` varchar(255) DEFAULT NULL,
   `edited` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
   `editedby_fk` int(5) NOT NULL DEFAULT '1',
   `viewed` tinyint(1) NOT NULL DEFAULT '0',
   `handled` int(1) NOT NULL DEFAULT '0',
   `archived` tinyint(1) NOT NULL DEFAULT '0',
    PRIMARY KEY (`id`),
    KEY `fk_physicianid` (`physician_fk`),
    KEY `fk_question01id` (`question01_fk`),
    KEY `fk_question02id` (`question02_fk`),
    KEY `fk_question03id` (`question03_fk`),
    KEY `fk_question04id` (`question04_fk`),
    KEY `fk_question05id` (`question05_fk`),
    KEY `fk_question06id` (`question06_fk`),
    KEY `fk_question07id` (`question07_fk`),
    KEY `fk_question08id` (`question08_fk`),
    KEY `fk_question09id` (`question09_fk`),
    KEY `fk_question10id` (`question10_fk`),
    KEY `fk_question11id` (`question11_fk`),
    KEY `fk_question12id` (`question12_fk`),
    KEY `fk_question13id` (`question13_fk`),
    KEY `fk_question14id` (`question14_fk`),
    KEY `fk_question15id` (`question15_fk`),
    KEY `fk_question16id` (`question16_fk`),
    KEY `fk_question17id` (`question17_fk`),
    KEY `fk_editedbyid` (`editedby_fk`),
    KEY `handled` (`handled`),
    KEY `scanned_index` (`datescanned`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=991 ; 

注意:所有問題都指向同一個表

選擇查詢

SELECT  q01.worth, q02.worth, q03.worth, q04.worth, q05.worth, q06.worth, q07.worth,
q08.worth, q09.worth, q10.worth, q11.worth, q12.worth, q13.worth, q14.worth, q15.worth,
q16.worth, q17.worth

FROM survey s, answer q01, answer q02, answer q03, answer q04,
answer q05, answer q06, answer q07, answer q08, answer q09, answer q10, answer q11,
answer q12, answer q13, answer q14, answer q15, answer q16, answer q17 

WHERE s.archived !=1 AND q01.id = s.question01_fk AND q02.id = s.question02_fk
AND q03.id = s.question03_fk AND q04.id = s.question04_fk AND q05.id = s.question05_fk
AND q06.id = s.question06_fk AND q07.id = s.question07_fk AND q08.id = s.question08_fk 
AND q09.id = s.question09_fk AND q10.id = s.question10_fk AND q11.id = s.question11_fk 
AND q12.id = s.question12_fk AND q13.id = s.question13_fk AND q14.id = s.question14_fk
AND q15.id = s.question15_fk AND q16.id = s.question16_fk AND q17.id = s.question17_fk

AND s.datescanned >=  '2013-11-18 00:00:00' AND s.datescanned <=  '2013-11-25 23:59:59';

注意:我已經嘗試使用和不使用INNER JOINs為question_fk

編輯:提請我注意,我需要重新考慮我的結構。 我將對此進行處理,如果可以解決,請更新或關閉此帖子。 謝謝那些到目前為止發表評論的人。

編輯2:這是一個結構問題。 拆分問題並映射到問題將整個報告從3分鍾以上縮短到20秒以內。 謝謝大家提供的指導。

盡管沒有從技術上回答問題,但這是我將使用的設計:

  • 調查: survey_id ,日期掃描等。
  • 問題: question_id ,描述等...
  • SURVEY_QUESTION: survey_idquestion_id

粗體顯示主鍵。 注意, SURVEY_QUESTION表具有一個復合鍵,其中既包含SURVEY的外鍵,又包含QUESTION的外鍵。

為了獲得所有帶有所有問題的問卷調查,您應該執行以下操作

SELECT * FROM survey s
JOIN survey_question sq on s.survey_id = sq.survey_id
JOIN question q on sq.question_id = q.question_id

與每個問題只有一列相比,這應該更快,更靈活。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM