以下使用LEFT JOIN的查询绘制了太多内存(~4GB),但主机只允许大约120MB进行此过程。
SELECT grades.grade, grades.evaluation_id, evaluations.evaluation_name, evaluations.value, evaluations.maximum FROM grades LEFT JOIN evaluations ON grades.evaluation_id = evaluations.evaluation_id WHERE grades.registrar_id = ?
为成绩创建表格语法:
CREATE TABLE `grades` (
`grade_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`evaluation_id` int(10) unsigned DEFAULT NULL,
`registrar_id` int(10) unsigned DEFAULT NULL,
`grade` float unsigned DEFAULT NULL,
`entry_date` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`grade_id`),
KEY `registrarGrade_key` (`registrar_id`),
KEY `evaluationKey` (`evaluation_id`),
KEY `grades_id_index` (`grade_id`),
KEY `eval_id_index` (`evaluation_id`),
KEY `grade_index` (`grade`),
CONSTRAINT `evaluationKey` FOREIGN KEY (`evaluation_id`) REFERENCES `evaluations` (`evaluation_id`),
CONSTRAINT `registrarGrade_key` FOREIGN KEY (`registrar_id`) REFERENCES `registrar` (`reg_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1627 DEFAULT CHARSET=utf8;
评估表:
CREATE TABLE `evaluations` (
`evaluation_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`instance_id` int(11) unsigned DEFAULT NULL,
`evaluation_col` varchar(255) DEFAULT NULL,
`evaluation_name` longtext,
`evaluation_method` enum('class','email','online','lab') DEFAULT NULL,
`evaluation_deadline` date DEFAULT NULL,
`maximum` int(11) unsigned DEFAULT NULL,
`value` float DEFAULT NULL,
PRIMARY KEY (`evaluation_id`),
KEY `instanceID_key` (`instance_id`),
KEY `eval_name_index` (`evaluation_name`(3)),
KEY `eval_method_index` (`evaluation_method`),
KEY `eval_deadline_index` (`evaluation_deadline`),
KEY `maximum` (`maximum`),
KEY `value_index` (`value`),
KEY `eval_id_index` (`evaluation_id`),
CONSTRAINT `instanceID_key` FOREIGN KEY (`instance_id`) REFERENCES `course_instance` (`instance_id`)
) ENGINE=InnoDB AUTO_INCREMENT=72 DEFAULT CHARSET=utf8;
用于提取数据的Php代码:
$sql = "SELECT grades.grade, grades.evaluation_id, evaluations.evaluation_name, evaluations.value, evaluations.maximum FROM grades LEFT JOIN evaluations ON grades.evaluation_id = evaluations.evaluation_id WHERE grades.registrar_id = ? AND YEAR(entry_date) = YEAR(CURDATE())";
$result = $mysqli->prepare($sql);
if($result === FALSE)
die($mysqli->error);
$result->bind_param('i',$reg_ids[$i]);
$result->execute();
$result->bind_result($grade, $eval_id, $evalname, $evalval, $max);
while($result->fetch()){
致命的错误消息
有没有办法大幅减少此查询的内存负载?
谢谢!
答案 0 :(得分:0)
请为这两个表提供SHOW CREATE TABLE
;我想知道你是否有这样的东西:
成绩:INDEX(registration_id)
评估:PRIMARY KEY(evaluation_id)
修改强>
你现在在两个表中都有冗余索引 - 可能是因为我的建议。也就是说,您已经拥有了有助于查询的索引。
由于你有LONGTEXT并且它试图准确分配4GB,LONGTEXT的最大大小,我想这就是问题所在。建议您将该列更改为TEXT(最大64KB)或MEDIUMTEXT(最大16MB)。我之前在PHP中没有看到过这种行为,但后来我很少使用比TEXT更大的东西。