简体   繁体   English

mysql计数投票优化

[英]mysql count votes optimization

so im making a file hub nothing huge or fancy just to store some files that may be shared by others for download. 因此,我将文件中枢变得没有什么大的或花哨的,仅仅是为了存储一些可能由其他人共享以供下载的文件。 and it just occured to me in the way that i originally intended to count the amount of upvotes or downvotes the query could be server heavy.the query to get the files is something along the lines of 而这对我来说只是我本来打算计算增票或减票数量的方式而发生的,查询可能是服务器沉重的。获取文件的查询类似于

select*from files;

and in such i would recieve an array of my files that i could loop over and get specifics on each file now with the inclusion of voting a file that same foreach loop would include a further query that would get the count the amount votes a file would get (the file id in the where clause) like so 这样,我将收到我的文件数组,可以循环遍历并获取每个文件的详细信息,包括对文件进行投票,相同的foreach循环将包含进一步的查询,该查询将获得对文件的表决数量像这样获取(where子句中的文件ID)

select*from votes where upvoted=true and file.id=?

and i was thinking of using pdo::rowCount to get my answer. 我在考虑使用pdo :: rowCount来获得我的答案。 now evey bone in my body just says this is bad very bad as imagine im getting 10,000 files i just ran 10,000 extra queries one on each file and i havent looked at the downvotes yet which i was think could go in a similar fasion. 现在,我体内的骨头只是说这很不好,因为我想得到10,000个文件,我只是在每个文件上运行了10,000个额外的查询,而我还没有查看过否决票,但我认为这可以以类似的方式进行。 any optimization adviece here is a small rep of the structure of a few tables. 这里的任何优化建议只是几个表的结构的一小部分。 the upvoted and downvoted columbs are of type bool or tinyint if you will 如果您愿意,升级后的列为bool或tinyint类型

   table: file                table: user                table: votes       
+----+-------------+    +----+-------------+ +--------+--------+--------+--------+
| id |storedname   |    | id | username    | |file_id | user_id| upvoted | downvoted
+----+-------------+    +----+-------------+ +--------+--------+--------+--------+ 
| 1  | 45tfvb.txt  |    | 1  | matthew     | | 1      |  2     |    1   |      0
| 2  |jj7fnfddf.pdf|    | 2  | mark        | | 2      |  1     |    1   |      1
| .. | ..          |    | .. | ..          | | ..     |  ..    |    ..  |      ..

Two advices: 两个建议:

  1. Avoid SELECT * especially if you're going to count. 避免使用SELECT *尤其是要计数时。 Replace it, with something like that: 用类似这样的东西替换它:

     SELECT COUNT(1) AS total WHERE upvoted=true AND file.id=? 
  2. Maybe you want to create a TRIGGER to keep update a counter in the file table. 也许您想创建一个TRIGGER来更新文件表中的计数器。

I hope it will be helpfull to you. 希望对您有帮助。

there are two ways to do this. 有两种方法可以做到这一点。 the better way to do this (aka faster) is to write separate queries and build into one variable in your programming language (like php, python.. etc.) 更好的方法(又名更快)是编写单独的查询并以您的编程语言(例如php,python等)构建到一个变量中。

SELECT 
    d.id as doc_id,
    COUNT(v.document_id) as num_upvotes
FROM votes v
JOIN document d on d.id = v.document_id
WHERE v.upvoted IS TRUE
GROUP BY doc_id
);

that will return your list of upvoted documents. 这将返回您已批准文件的列表。 you can do the same for your downvotes. 您也可以对下注进行相同的操作。

then after your select from document do a for loop to compare the votes with the document by ID and build into a dictionary or list. 然后,从文档中选择之后,进行for循环,以按ID将投票与文档进行比较,并构建成词典或列表。


The second way to do this which can take a lot longer at runtime if you have a bunch of records in the table (its less efficient, but easier to write) is to add subquery selects in your select statement like this... 如果您在表中有一堆记录(效率较低,但更容易编写),则第二种方法可能会在运行时花费更多时间(例如,在子查询中添加子查询选择)。

SELECT 
    logical_name ,
    document.id , 
    file_type , 
    physical_name , 
    uploader_notes , 
    views , 
    downloads , 
    user.name , 
    category.name AS category_name,
    (Select count(1) from votes where upvoted=true and document_id=document.id )as upvoted,
    (select count(1) from votes where upvoted=false and document_id=document.id) as downvoted 
FROM document 
INNER JOIN category ON document.category_id = category.id 
INNER JOIN user ON document.uploader_id = user.id 
ORDER BY category.id

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM