Jam*_*D31 0 php mysql sql performance
好的,所以我的托管公司暂停我的帐户第四次该死的时间.这让我很烦,因为他们说的代码导致了这个问题:
# Mon Mar 5 11:00:00 2012
# Query_time: 4.028706 Lock_time: 0.000272 Rows_sent: 15 Rows_examined: 12188513 use futureg2_imbc;
SELECT uploadsNew.id ,
uploadsNew.title , uploadsNew.genre , uploadsNew.content ,
uploadsNew.url , uploadsNew.approved, (IF(v.views IS NOT NULL,
v.views, 0) + IF(vc.old_views IS NOT NULL, vc.old_views, 0)) AS views,
r.likes , r.dislikes FROM uploadsNew
LEFT JOIN
(SELECT id ,
COUNT(*) AS views
FROM views
WHERE type = '0' AND subtype = '1'
GROUP BY id
) AS v
ON v.id = uploadsNew.id
LEFT JOIN
(SELECT
id , SUM(views) AS old_views
FROM viewsCondensed
WHERE type = '0' AND subtype = '1'
GROUP BY id
) AS vc
ON vc.id = uploadsNew.id
LEFT JOIN
(SELECT upload , SUM(IF(rating = '1', 1, 0)) AS likes ,
SUM(IF(rating = '-1', 1, 0)) AS dislikes ,
IF(username = '', rating, 0) AS user_rated
FROM ratingNew
WHERE ratingNew.type = '0'
GROUP BY upload ) AS r
ON r.upload = uploadsNew.id
WHERE uploadsNew.type = '1' AND uploadsNew.status ='0' AND
uploadsNew.school = 'illinois-state-university'
GROUP BY
uploadsNew.id ORDER BY uploadsNew.approved DESC LIMIT 15
Run Code Online (Sandbox Code Playgroud)
不能在我的页面上运行.即使在每次更改我的代码并且100次查看它之后,这仍然是一个问题,并且它是完全相同的代码,每次运行多次,每次他们暂停我的帐户.
这是PHP代码:
$sql = "SELECT uploadsNew.id
, uploadsNew.title
, uploadsNew.genre
, uploadsNew.content
, uploadsNew.url
, uploadsNew.approved";
if($type < 3) $sql .= ", (IF(v.views IS NOT NULL, v.views, 0) + IF(vc.old_views IS NOT NULL, vc.old_views, 0)) AS views";
else $sql .= ", uploadsNew.member
, uploadsNew.anonymous
, r.ratedSong";
$sql .= ", r.likes
, r.dislikes";
if($sort == "rated") $sql .= ", (r.likes - r.dislikes) AS rating";
if(isset($school)) $sql .= ", s.school_id";
$sql .= " FROM uploadsNew";
if(isset($school)) $sql .= " LEFT JOIN (SELECT url, id AS school_id FROM schools) AS s ON s.url = '". $school ."'";
$sql .= " LEFT JOIN
(SELECT id
, COUNT(*) AS views
FROM views
WHERE type = '0' AND subtype = '". $type ."'
GROUP BY id
) AS v
ON v.id = uploadsNew.id
LEFT JOIN
(SELECT id
, SUM(views) AS old_views
FROM viewsCondensed
WHERE type = '0' AND subtype = '". $type ."'
GROUP BY id
) AS vc
ON vc.id = uploadsNew.id
LEFT JOIN
(SELECT upload
, SUM(IF(rating = '1', 1, 0)) AS likes
, SUM(IF(rating = '-1', 1, 0)) AS dislikes
, IF(username = '". $user['username'] ."', rating, 0) AS user_rated
FROM ratingNew
WHERE ratingNew.type = '0'
GROUP BY upload
) AS r
ON r.upload = uploadsNew.id
WHERE uploadsNew.type = '". $type ."' AND uploadsNew.status = '0'";
if($genre) $sql .= " AND uploadsNew.genre = '". strtolower($genre) ."'";
if(isset($school)) $sql .= " AND uploadsNew.school = s.school_id";
else $sql .= $filter;
$sql .= " GROUP BY uploadsNew.id ORDER BY ". $s ." LIMIT ". ($page - 1) * $limit .", ". $limit;
Run Code Online (Sandbox Code Playgroud)
如果有人甚至可以弄清楚上面引用的代码甚至可以从单个查询中运行 - 请随意.此外,如果你能弄清楚它是如何每秒运行多次(就好像它是循环的)我会更爱你.
另外,上述方法是否有效?我有另一个关于此问题的线索(以及一般的数据库),没有人回答过我的问题.
支持给了我很少的帮助,并不断向我推荐明显的东西.我觉得最重要的是自从viewsCondensed表大约是〜80k的东西.
基本上,viewsCondensed表用于将所有内容(在视图表中)的每日视图压缩为完全每日总和(viewsCondensed).
我应该把它改成每周的东西,还是每月的东西?我曾经把所有这些只是在uploadsNew表中的一部分,虽然我觉得这样效率有点低,并且不允许每天保存实际数据.
任何和所有帮助都会得到很多赞赏!
对不起,这里有关于SELECT以及各种表的EXPLAIN的更多数据:
这是一个NORMAL查询,它在前一个"运行"的页面上运行:
SELECT uploadsNew.id
, uploadsNew.title
, uploadsNew.genre
, uploadsNew.content
, uploadsNew.url
, uploadsNew.approved, (IF(v.views IS NOT NULL, v.views, 0) + IF(vc.old_views IS NOT NULL, vc.old_views, 0)) AS views, r.likes
, r.dislikes FROM uploadsNew
LEFT JOIN
(SELECT id
, COUNT(*) AS views
FROM views
WHERE type = '0' AND subtype = '1'
GROUP BY id
) AS v
ON v.id = uploadsNew.id
LEFT JOIN
(SELECT id
, SUM(views) AS old_views
FROM viewsCondensed
WHERE type = '0' AND subtype = '1'
GROUP BY id
) AS vc
ON vc.id = uploadsNew.id
LEFT JOIN
(SELECT upload
, SUM(IF(rating = '1', 1, 0)) AS likes
, SUM(IF(rating = '-1', 1, 0)) AS dislikes
, IF(username = '', rating, 0) AS user_rated
FROM ratingNew
WHERE ratingNew.type = '0'
GROUP BY upload
) AS r
ON r.upload = uploadsNew.id
WHERE uploadsNew.type = '1'
AND uploadsNew.status = '0'
GROUP BY uploadsNew.id ORDER BY uploadsNew.approved DESC LIMIT 15
Run Code Online (Sandbox Code Playgroud)
解释上面的内容:
1 PRIMARY uploadsNew ref type,type_2 type_2 8 const,const 1965 Using temporary; Using filesort
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 1335
1 PRIMARY <derived3> ALL NULL NULL NULL NULL 5429
1 PRIMARY <derived4> ALL NULL NULL NULL NULL 372
4 DERIVED ratingNew ALL NULL NULL NULL NULL 2111 Using where; Using temporary; Using filesort
3 DERIVED viewsCondensed ref type,type_2,type_3,type_4 type_2 8 67475 Using where; Using temporary; Using filesort
2 DERIVED views index type id_2 12 NULL 4351 Using where; Using index
Run Code Online (Sandbox Code Playgroud)
解释最初的"问题"查询:
1 PRIMARY uploadsNew ref type,type_2 type_2 8 const,const 1896使用where; 使用临时; 使用filesort 1 PRIMARY ALL NULL NULL NULL 479 1 PRIMARY ALL NULL NULL NULL NULL 6015
1 PRIMARY ALL NULL NULL NULL NULL 384 4 DERIVED ratingNew ALL NULL NULL NULL NULL 2171使用where; 使用临时; 使用filesort 3 DERIVED viewsCondensed ref type,type_2,type_3,type_4 type_3 4 53779使用where; 使用临时; 使用filesort 2 DERIVED视图ref类型类型4 688使用where; 使用临时; 使用filesort
观点表:
CREATE TABLE
views(idint(10)NOT NULL DEFAULT'0',typeint(1)NOT NULL DEFAULT'0',subtypeint(1)NOT NULL DEFAULT'0',datedatetime NOT NULL,ipint(20)NOT NULL DEFAULT'0' ,userVARCHAR(20)NOT NULL,KEYid(id,type),KEYid_2(id,type,subtype),KEYid_3(id,type,date),KEYtype(type,ip))ENGINE = MyISAM的默认字符集= LATIN1
viewsCondensed表:
CREATE TABLE
viewsCondensed(idint(10)NOT NULL DEFAULT'0',typeint(1)NOT NULL DEFAULT'0',subtypeint(1)NOT NULL DEFAULT'0',datedate NOT NULL,viewsint(10)NOT NULL DEFAULT'0' ,KEYid(id,type),KEYid_2(id,type,subtype),KEYid_3(id,type,date),KEYtype(type,views),KEYtype_2(type,subtype,views),KEYtype_3(type,date,views),KEYtype_4(type))ENGINE = MyISAM的默认字符集= LATIN1
uploadsNew表:
CREATE TABLE
uploadsNew(idint(10)NOT NULL AUTO_INCREMENT,membervarchar(30)NOT NULL,ipint(20)NOT NULL,galleryvarchar(30)NOT NULL,typeint(1)NOT NULL,genrevarchar(30)NOT NULL,anonymousint(1) NOT NULL,schoolINT(6)NOT NULL,added日期时间NOT NULL,approved日期时间NOT NULL,titleVARCHAR(255)NOT NULL,contentVARCHAR(2500)NOT NULL,urlVARCHAR(300)NOT NULL,addressVARCHAR(40)NOT NULL,tagsVARCHAR(200) NOT NULL,ratingINT(1)NOT NULL,statusINT(1)NOT NULL,sourceVARCHAR(600)NOT NULL,PRIMARY KEY(id),KEYid(id,member,status),KEYtype(type,genre,approved,rating,status),KEYtype_2(type,status))ENGINE = MyISAM AUTO_INCREMENT = 6004 DEFAULT CHARSET = latin1
评级新表:
CREATE TABLE
ratingNew(uploadint(10)NOT NULL,typeint(1)NOT NULL DEFAULT'0',usernamevarchar(20)NOT NULL,ipint(16)NOT NULL,ratingint(1)NOT NULL,datedatetime NOT NULL,KEYupload(upload,type) )ENGINE = MyISAM DEFAULT CHARSET = latin1
更多编辑(尝试新的查询和解释):
新查询
SELECT
uploadsNew.id, uploadsNew.title,
uploadsNew.genre, uploadsNew.content,
uploadsNew.url, uploadsNew.approved,
COALESCE(v.views, 0) + COALESCE(vc.old_views, 0) AS views,
r.likes, r.dislikes
FROM ( SELECT *
FROM uploadsNew
WHERE type = 1
AND status = 0
ORDER BY approved DESC
LIMIT 15
) AS uploadsNew
LEFT JOIN
( SELECT id, COUNT(*) AS views
FROM views
WHERE type = 0 AND subtype = 1
GROUP BY id
) AS v ON v.id = uploadsNew.id
LEFT JOIN
( SELECT id, SUM(views) AS old_views
FROM viewsCondensed
WHERE type = 0 AND subtype = 1
GROUP BY id
) AS vc ON vc.id = uploadsNew.id
LEFT JOIN
( SELECT upload,
SUM(rating = 1 ) AS likes,
SUM(rating = -1) AS dislikes,
IF(username = '', rating, 0) AS user_rated
FROM ratingNew
WHERE type = 0
GROUP BY upload
) AS r ON r.upload = uploadsNew.id
ORDER BY uploadsNew.approved DESC
Run Code Online (Sandbox Code Playgroud)
解释
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 15 Using temporary; Using filesort
1 PRIMARY <derived3> ALL NULL NULL NULL NULL 479
1 PRIMARY <derived4> ALL NULL NULL NULL NULL 6015
1 PRIMARY <derived5> ALL NULL NULL NULL NULL 384
5 DERIVED ratingNew index NULL upload_3 34 NULL 2171 Using where; Using index
4 DERIVED viewsCondensed ref type,type_2,type_3,type_4 type_3 4 53779 Using where; Using temporary; Using filesort
3 DERIVED views ref type type 4 688 Using where; Using temporary; Using filesort
2 DERIVED uploadsNew range type,type_2,type_3,type_4 type_4 4 NULL 5970 Using where
Run Code Online (Sandbox Code Playgroud)
是什么PRIMARY KEY的uploadsNew?是id吗?如果是,请删除GROUP BY uploadsNew.id.它应该给出相同的结果.
你在桌子上有什么指数?如果还没有,请添加:
(type, subtype, id)表中的索引views (type, subtype, id, views)表中的索引viewsCondensed.(type, upload, rating)表中的索引 ratingNew.(type, status, school, approved)表中的索引uploadsNew.然后,(不要运行查询),但使用EXPLAIN语句获取查询计划并在此处发布.如果添加表的定义(因此我们知道您拥有的数据类型和索引)也会很好.
你的几张桌子没有PRIMARY KEY.这不好,但这并不是这两个查询缓慢的原因,所以暂时忘记它(但你应该稍后处理).
你有几个冗余索引,但这不是上述查询性能下降的原因,所以我们也跳过这个(但是你也应该稍后处理).
添加我在上面的评论2中添加的索引.唯一可能不是最好的是(type, upload, rating)表格ratingNew.它可能必须是:(type, upload, username, rating)相反,但如果该表没有很多行,它现在不会成为问题.
您的代码会生成查询的多个变体.所以,你们许多人也必须添加这个索引:(type, status, approved)在表中uploadsNew.
然后,首先尝试解析此变体,然后运行它:
SELECT
uploadsNew.id, uploadsNew.title,
uploadsNew.genre, uploadsNew.content,
uploadsNew.url, uploadsNew.approved,
COALESCE(v.views, 0) + COALESCE(vc.old_views, 0) AS views,
r.likes, r.dislikes
FROM ( SELECT *
FROM uploadsNew
WHERE type = 1
AND status = 0
AND school = 'illinois-state-university'
ORDER BY approved DESC
LIMIT 15
) AS uploadsNew
LEFT JOIN
( SELECT id, COUNT(*) AS views
FROM views
WHERE type = 0 AND subtype = 1
GROUP BY id
) AS v ON v.id = uploadsNew.id
LEFT JOIN
( SELECT id, SUM(views) AS old_views
FROM viewsCondensed
WHERE type = 0 AND subtype = 1
GROUP BY id
) AS vc ON vc.id = uploadsNew.id
LEFT JOIN
( SELECT upload,
SUM(rating = 1 ) AS likes,
SUM(rating = -1) AS dislikes,
IF(username = '', rating, 0) AS user_rated
FROM ratingNew
WHERE type = 0
GROUP BY upload
) AS r ON r.upload = uploadsNew.id
ORDER BY uploadsNew.approved DESC
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
286 次 |
| 最近记录: |