简体   繁体   English

mysql选择缓存优化

[英]mysql select cache optimization

Having a table called 'books', then multiple tables with a primary key, and value: EG 'library', and 'genre'. 有一个名为“ books”的表,然后有多个带有主键和值的表:例如EG“ library”和“ genre”。 Then this primary key is stored in the 'books' table for every book. 然后,该主键将存储在每本书籍的“书籍”表中。

What's an efficient way to retrieve all books in library A? 什么是检索库A中所有书籍的有效方法?

Some approaches: 一些方法:

  • Select using inner join and sort on library column - innefficient with temporary tables? 选择使用内部联接并在库列上排序-临时表效率低下吗? Clever way to index the data to make this fast? 聪明的方法来索引数据,以使之快速?
  • Copy the text value into the 'books' table instead of primary key - inconsistent database? 将文本值复制到“ books”表中而不是主键中-数据库不一致?
  • Using a sub query select books where library = (select id where library = 'A') - mysql caches the sub query? 使用子查询select books where library = (select id where library = 'A') -mysql缓存子查询?
  • Send two queries, and cache the primary id of library A in php/memcached - messy implementation? 发送两个查询,并将库A的主ID缓存在php / memcached中-混乱的实现?

What's the reccomended (and fast) way of doing this? 推荐的(快速)方法是什么?

Use a relational model between libraries and books and query it using joins. 在图书馆和书籍之间使用关系模型,并使用联接对其进行查询。 This is fairly fast, as long as you have the primary keys and indexes for library_id set up. 只要您设置了library_id的主键和索引,这就相当快。

table: libraries
+-------+--------------+------+-----+---------+-------+
| Field | Type         | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| id    | int(11)      | YES  | PRI | NULL    |       |
| name  | varchar(100) | NO   |     | NULL    |       |
+-------+--------------+------+-----+---------+-------+
+------+------+
| id   | name |
+------+------+
|    1 | Foo  |
|    2 | Bar  |
+------+------+

table: books
+------------+--------------+------+-----+---------+-------+
| Field      | Type         | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+-------+
| id         | int(11)      | NO   | PRI | 0       |       |
| library_id | int(11)      | NO   | MUL | NULL    |       |
| author     | varchar(100) | NO   |     | NULL    |       |
| name       | varchar(100) | NO   |     | NULL    |       |
+------------+--------------+------+-----+---------+-------+
+----+------------+--------+------+
| id | library_id | author | name |
+----+------------+--------+------+
|  1 |          1 | Jon    | Baz  |
|  2 |          1 | Bill   | Baz  |
|  3 |          2 | Mary   | Abc  |
+----+------------+--------+------+

This allows for very easy querying. 这使得查询非常容易。 To find all books in the library with the name of 'Foo', you'd use a query like this: 要在图书馆中查找所有名称为“ Foo”的书籍,请使用类似以下的查询:

mysql> SELECT books.* FROM books
    -> JOIN libraries ON libraries.id = books.library_id
    ->  AND libraries.name = 'Foo';
+----+------------+--------+------+
| id | library_id | author | name |
+----+------------+--------+------+
|  1 |          1 | Jon    | Baz  |
|  2 |          1 | Bill   | Baz  |
+----+------------+--------+------+

If you already know the library ID, you don't even need a join: 如果您已经知道库ID,那么您甚至不需要加入:

mysql> SELECT * FROM books
    -> WHERE library_id = 2;
+----+------------+--------+------+
| id | library_id | author | name |
+----+------------+--------+------+
|  3 |          2 | Mary   | Abc  |
+----+------------+--------+------+

If you want performance on a relation database you must use Foreign Keys. 如果要提高关系数据库的性能,则必须使用外键。 Indexes are fast but FK's are faster simply because they 'know' what on the other end. 索引速度很快,但是FK速度更快,这仅仅是因为它们“知道”另一端的内容。 If you are still having performance issues after that you must first understand how the DB engine handles your request. 如果之后仍然遇到性能问题,则必须首先了解数据库引擎如何处理您的请求。 If you have a lot of books and only a few libraries make sure the engine selects your library first; 如果您有很多书并且只有几个图书馆,请确保引擎首先选择您的图书馆;否则,请执行以下步骤。 not 'books inner join library' but 'library inner join books'. 不是“书籍内部连接库”,而是“图书馆内部连接书”。 If you don't use data from both tables you must go for subqueries, 'cause that way the engine will only use the keys from the subqueries for the join, instead of the complete table. 如果您不使用两个表中的数据,则必须使用子查询,因为这样引擎将仅使用子查询中的键进行连接,而不使用完整表。 Never use your (PHP)-code to cache database results for the next query. 永远不要使用(PHP)代码为下一个查询缓存数据库结果。 If things are getting to complex to get done in one go use temporary table. 如果事情变得复杂起来,请使用临时表。

I would go for : 我会去:

  • A single SQL query 单个SQL查询
  • With an inner join between the books and library 通过bookslibrary之间的内在联系

After all, that's the most logical thing to do, in this kind of situation, considering : 毕竟,在这种情况下,考虑以下几点是最合乎逻辑的:

  • You are using a relational database system 您正在使用关系数据库系统
  • And your data seems properly structured. 而且您的数据似乎结构正确。


If you want to optimize things a little, yes, you could use your last point ; 如果您想稍微优化一些东西,是的,您可以使用最后一点; but not sure that would change much actually : 但不确定实际上会发生很大变化:

  • You would send two queries to the database 您将向数据库发送两个查询
  • Using the correct indexes (you probably are, if using foreign keys and InnoDB) , one single query should work quite fast. 使用正确的索引(如果使用外键和InnoDB您可能会使用正确的索引 ,单个查询应该运行得很快。

If I were to add some cache, I would probably cache the result of the whole book-search. 如果要添加一些缓存,则可能会缓存整个图书搜索的结果。

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

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