Note that there are some explanatory texts on larger screens.

plurals
  1. POSlow MySQL query when datetime between in where clause
    primarykey
    data
    text
    <p>I have a table that takes in a patient satisfaction survey (create statement at bottom) with 17 questions and a few text blocks. It sets a datetime field when the survey is entered into the database. I have to be able to run reports on averages for time periods (weeks/months/years). Currently, I am running queries in weekly slices.</p> <p>My queries are taking up to 16s to run, and max the CPU during the run. I then have to do that query for 13 more weeks to get a global average, then I do the query 14 <strong>more</strong> times per selected doctor(can be between 0 and 22 times).</p> <p>I have tried using <code>WHERE date &gt;= 'date low' AND date &lt;= 'date high'</code>, <code>WHERE date BETWEEN 'date low' AND 'date high'</code>, and I have tried <code>CAST('date' as datetime)</code> to no avail. When profiling the query, it seems to spend the bulk of its time on <code>statistics</code> and an <code>EXPLAIN</code> seems to be saying it is not using the datescanned index, but I don't know why.</p> <p>There are about 1000 rows currently, but the queries ran fine when there were about half that number of rows. From that, I gather that I have a pretty bad problem with either how I created the table, or how I'm forming my queries.</p> <p>NOTE: running on Debian 7.2 on VMWare ESXi 5.1 with 4GB mem and 1 virtual proc</p> <p><strong>Create Table:</strong></p> <pre><code>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 ; </code></pre> <p>NOTE: all questions point to the same table</p> <p><strong>Select Query</strong></p> <pre><code>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 &gt;= '2013-11-18 00:00:00' AND s.datescanned &lt;= '2013-11-25 23:59:59'; </code></pre> <p>NOTE: I have tried with and without INNER JOINs for the question_fk</p> <p>EDIT: It has been brought to my attention that I need to rethink my structure. I will work on that and either update or close this post if that fixes it. Thank you to those who have commented so far.</p> <p>EDIT 2: It was a structure problem. Splitting out the questions and mapping to them dropped the full report to under 20 seconds, from over 3 minutes. Thank you everyone who provided guidance.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload