转贴一个有关MYSQL的文章.E文的.MySQLs Query Cache
cache|mysql
A typical scenario
Boss: Our new website is crawling! How can it be, we have four state-of-the-art web servers - what's the problem?
You: Well, the web servers are fine - it's the database server that's struggling.
Boss: What? You told me this MySQL thing was fast, that we didn't need Oracle, and now you say it can't cope! How can this be?
You: Well, the web servers are behaving so well that they're pushing through lots of queries, and the database can't manage to process all of them at the same time. It's only one database, and lots of web servers...
Boss: It's too late to buy Oracle now - what are we going to do!?
Big Boss to Boss(in the boss's mind): This project has been a disaster from the beginning - now you want me to delay it while we install a new database, and spend a whole lot more! Do you think we're made of money!? I'm calling in someone who knows what they're doing - you're history buddy.
Colleague (about to take your job): Wait, I think I can solve the problem!
So, what does your colleague know that you don't? How can he save the day and let the boss get all the credit? Our scenario is too imprecise to generalize, and there are many possible solutions. You can read about optimizing queries and indexes, optimizing by improving the hardware, and tweaking the MySQL variables, using the slow query log, and of course, there are other methods such as replication. However, MySQL 4 provides one feature that can prove very handy - a query cache. In a situation where the database has to repeatedly run the same queries on the same data set, returning the same results each time, MySQL can cache the result set, avoiding the overhead of running through the data over and over. Usually, you would want to implement some sort of caching on the web server, but there are times when this is not possible, and then it is the query cache you will look to for help.
Setting up the query cache
To make sure MySQL uses the query cache, there are a few variables you need to set in the configuration file (usually my.cnf or my.ini). First, is the query_cache_type. There are three possible settings: 0 (for off, do not use), 1 (for on, cache queries) and 2 (on demand, discussed more below). To ensure it is always on, place:
query-cache-type = 1
in the configuration file. If you started the server having only made this change, you would see the following cache variables set:
mysql> SHOW VARIABLES LIKE '%query_cache%';
+-------------------+---------+
| Variable_name | Value |
+-------------------+---------+
| have_query_cache | YES |
| query_cache_limit | 1048576 |
| query_cache_size | 0 |
| query_cache_type | ON |
+-------------------+---------+
4 rows in set (0.06 sec)
Note that these are results from MySQL 4.0.x - you'll see more in versions 4.1.x and beyond. The query_cache_type will be set to ON or OFF as appropriate. However, there is one more to set, and that is the query_cache_size. If set to 0 (the default), the cache will be disabled. This variable determines the memory, in bytes, used for the query cache. For our purposes, we will set it to 20 MB:
query-cache-size = 20M
The amount is shown in bytes:
mysql> SHOW VARIABLES LIKE '%query_cache%';
+-------------------+----------+
| Variable_name | Value |
+-------------------+----------+
| have_query_cache | YES |
| query_cache_limit | 1048576 |
| query_cache_size | 20971520 |
| query_cache_type | ON |
+-------------------+----------+
4 rows in set (0.06 sec)
The Query cache in action (almost)
For this tutorial, I used a dump from Wikipedia, the open content encyclopedia (you can find the dumps here. I am using a fairly slow machine, with nothing else happening on it, to minimize interference in the results. Let's run the same query twice, and see how much improvement we see the second time:
SELECT * FROM cur;
...
14144 rows in set (2.96 sec)
Now we run the same query again:
SELECT * FROM cur; 14144 rows in set (3.02 sec)
Now we run the same query again:
SELECT * FROM cur; 14144 rows in set (3.02 sec)
What is happening? We would expect the second query to take noticeably less time. Let's examine some of the status variables to get a better picture.
mysql> SHOW STATUS LIKE '%qcache%';
+-------------------------+----------+
| Variable_name | Value |
+-------------------------+----------+
| Qcache_queries_in_cache | 0 |
| Qcache_inserts | 2 |
| Qcache_hits | 0 |
| Qcache_lowmem_prunes | 0 |
| Qcache_not_cached | 2 |
| Qcache_free_memory | 20962720 |
| Qcache_free_blocks | 1 |
| Qcache_total_blocks | 1 |
+-------------------------+----------+
8 rows in set (0.00 sec)
The two queries we ran are both recorded (by Qcache_inserts), but neither of them have been cached. (You may get different results if other queries have been running.) The problem is that the result set is too big. I used the Wikipedia Esperanto dump (4MB compressed - the English dump is 135MB, and even though my English is better than my Esperanto, bandwidth is expensive in South Africa!), but it is immaterial, as even that is more than the query cache can handle by default. There are two limits in play here - the limit for each individual query is determined by the value of query_cache_limit, which is 1MB by default. Moreover, the limit of the cache in total is determined by query_cache_size, which we have seen already. The former limit applies here. If a result set is greater than 1M, it is not cached.
The Query cache in action (really)
Let's try a smaller query:
SELECT cur_is_new FROM cur WHERE cur_user_text > 'Y'
...
2336 rows in set (0.38 sec)
Let's see if this one was cached:
mysql> SHOW STATUS LIKE '%qcache%';
+-------------------------+----------+
| Variable_name | Value |
+-------------------------+----------+
| Qcache_queries_in_cache | 1 |
| Qcache_inserts | 3 |
| Qcache_hits | 0 |
| Qcache_lowmem_prunes | 0 |
| Qcache_not_cached | 2 |
| Qcache_free_memory | 20947592 |
| Qcache_free_blocks | 1 |
| Qcache_total_blocks | 4 |
+-------------------------+----------+
8 rows in set (0.00 sec)
There is now a query in the cache. If it took 0.38 seconds to run the first time, let's see if we notice an improvement the second time:
SELECT cur_is_new FROM cur WHERE cur_user_text > 'Y'
...
2336 rows in set (0.11 sec)
Much better! And, looking at the status again:
mysql> SHOW STATUS LIKE '%qcache%';
+-------------------------+----------+
| Variable_name | Value |
+-------------------------+----------+
| Qcache_queries_in_cache | 1 |
| Qcache_inserts | 3 |
| Qcache_hits | 1 |
| Qcache_lowmem_prunes | 0 |
| Qcache_not_cached | 2 |
| Qcache_free_memory | 20947592 |
| Qcache_free_blocks | 1 |
| Qcache_total_blocks | 4 |
+-------------------------+----------+
8 rows in set (0.06 sec)
The cache has been hit once. The status variables above should be fairly self-explanatory. Available memory for the cache has gone from 20962720 to 20947592 bytes. The most useful variable for future tuning is Qcache_lowmem_prunes. Each time a cached query is removed from the query cache, (because MySQL needs to make space for another), this value will be incremented. If it increases quickly, and you still have memory to spare, you can up the query_cache_size, while if it never increases, you can reduce the cache size.
Let's run the query again, with a slight difference, as follows:
SELECT cur_is_new from cur where cur_user_text > 'Y'
...
2336 rows in set (0.33 sec)
That took longer than we would have expected. Let's look at the status variables to see what's up:
mysql> SHOW STATUS LIKE '%qcache%';
+-------------------------+----------+
| Variable_name | Value |
+-------------------------+----------+
| Qcache_queries_in_cache | 2 |
| Qcache_inserts | 4 |
| Qcache_hits | 1 |
| Qcache_lowmem_prunes | 0 |
| Qcache_not_cached | 2 |
| Qcache_free_memory | 20932976 |
| Qcache_free_blocks | 1 |
| Qcache_total_blocks | 6 |
+-------------------------+----------+
The query has not made use of the cache - in fact, MySQL has inserted another query in the cache! The problem here is that MySQL's query cache is case-sensitive (in fact it is byte sensitive). The query must be identical in every way - no extra spaces, no changes in case. Therefore, the above query is treated as a different query. This fact alone should be enough for you to adopt a certain convention, and ensure all application developers make use of it. I use caps for MySQL keywords, and lower case for table and field names.
Clearing the Query cache
The cache cannot stay in memory indefinitely. Luckily, MySQL is clever enough to clear it when you make any changes to the tables used in a cache query. If we insert a new record to the cur table, MySQL will clear the affected queries (and only the affected queries) from the cache:
mysql> INSERT INTO cur(cur_user_text)
VALUES ('xxx');
Query OK, 1 row affected (0.06 sec)
mysql> SHOW STATUS LIKE '%qcache%';
+-------------------------+----------+
| Variable_name | Value |
+-------------------------+----------+
| Qcache_queries_in_cache | 0 |
| Qcache_inserts | 4 |
| Qcache_hits | 1 |
| Qcache_lowmem_prunes | 0 |
| Qcache_not_cached | 2 |
| Qcache_free_memory | 20962720 |
| Qcache_free_blocks | 1 |
| Qcache_total_blocks | 1 |
+-------------------------+----------+
Any of INSERT, UPDATE, DELETE, TRUNCATE, ALTER, DROP TABLE or DROP DATABASE potentially remove queries from the cache. You can manually clear the query cache with RESET QUERY CACHE.
Query Cache on demand
Earlier we saw there were three values for the query_cache_type. On, off and on demand. The latter option means that queries will only be cached if SQL_CACHE is specified in the query. Let's restart the server, with
query-cache-type = 2
in the configuration. Restarting the server flushes all the status variables. We run our previous query again:
SELECT cur_is_new FROM cur WHERE cur_user_text > 'Y'
...
2336 rows in set (0.27 sec)
It is back to a longer time again, as the cache has been flushed.
mysql> SHOW STATUS LIKE '%qcache%';
+-------------------------+----------+
| Variable_name | Value |
+-------------------------+----------+
| Qcache_queries_in_cache | 0 |
| Qcache_inserts | 0 |
| Qcache_hits | 0 |
| Qcache_lowmem_prunes | 0 |
| Qcache_not_cached | 1 |
| Qcache_free_memory | 20962720 |
| Qcache_free_blocks | 1 |
| Qcache_total_blocks | 1 |
+-------------------------+----------+
Nothing has been recorded. To store a query in the cache, we need to run the query with SQL_CACHE, as follows:
SELECT SQL_CACHE cur_is_new FROM cur WHERE cur_user_text > 'Y'
...
2336 rows in set (0.33 sec)
This time it has been stored in the cache.
mysql> SHOW STATUS LIKE '%qcache%';
+-------------------------+----------+
| Variable_name | Value |
+-------------------------+----------+
| Qcache_queries_in_cache | 1 |
| Qcache_inserts | 1 |
| Qcache_hits | 0 |
| Qcache_lowmem_prunes | 0 |
| Qcache_not_cached | 1 |
| Qcache_free_memory | 20947592 |
| Qcache_free_blocks | 1 |
| Qcache_total_blocks | 4 |
+-------------------------+----------+
If the cache type is set to 1, there may be times when you know the query you are running will not be repeated, or more infrequently. In these situations, you can ask MySQL not to store the results in the cache, even if they adhere to the size limitations, with the SQL_NO_CACHE clause in the SELECT statement.
Block allocation and the Query cache
MySQL allocates results into the cache in blocks, during retrieval. This allocation comes at an overhead (see the quicker time to run the above query when it was not being cached). You should not enable the query cache unless you can make good use of it. The number of free blocks (Qcache_free_blocks) can be an indication of fragmentation - a high number in relation to the total number of the blocks means that space is being wasted. In MySQL 4.1, there is another cache-related variable: query_cache_min_res_unit. This allows you to set a minimum block size. The default is 4KB. If most of your query results are small, and you see fragmentation, you should decrease this. The converse applies if most of your result sets are large. To defragment a query cache, you can use FLUSH QUERY CACHE (FLUSH TABLES has the same effect on the cache).
There are situations when a query cannot be cached, all of which make perfect sense, such as when returning the current time, a random number, user variables, or when dumping to a file. Any queries making use of the following functions, or of the following types, will not be cached:
User-Defined Functions
BENCHMARK
CONNECTION_ID
CURDATE
CURRENT_DATE
CURRENT_TIME
CURRENT_TIMESTAMP
CURTIME
DATABASE
ENCRYPT (with one parameter)
FOUND_ROWS
GET_LOCK
LAST_INSERT_ID
LOAD_FILE
MASTER_POS_WAIT
NOW
RAND
RELEASE_LOCK
SYSDATE
UNIX_TIMESTAMP (without parameters)
USER
query contains user variables
query references the mysql system database
query of the form SELECT ... IN SHARE MODE
query of the form SELECT ... INTO OUTFILE ...
query of the form SELECT ... INTO DUMPFILE ...
query of the form SELECT * FROM AUTOINCREMENT_FIELD IS NULL
queries inside transactions (in MySQL 4.0.x)
Wisely used, the query cache can make a substantial difference to struggling applications. Good luck!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











로그인 화면에 "귀하의 조직에서 PIN 변경을 요구합니다"라는 메시지가 나타납니다. 이는 개인 장치를 제어할 수 있는 조직 기반 계정 설정을 사용하는 컴퓨터에서 PIN 만료 제한에 도달한 경우 발생합니다. 그러나 개인 계정을 사용하여 Windows를 설정하는 경우 이상적으로는 오류 메시지가 나타나지 않습니다. 항상 그런 것은 아니지만. 오류가 발생한 대부분의 사용자는 개인 계정을 사용하여 신고합니다. 조직에서 Windows 11에서 PIN을 변경하도록 요청하는 이유는 무엇입니까? 귀하의 계정이 조직과 연결되어 있을 수 있으므로 이를 확인하는 것이 기본 접근 방식입니다. 도메인 관리자에게 문의하면 도움이 될 수 있습니다! 또한 잘못 구성된 로컬 정책 설정이나 잘못된 레지스트리 키로 인해 오류가 발생할 수 있습니다. 지금 바로

Windows 11은 신선하고 우아한 디자인을 전면에 내세웠습니다. 현대적인 인터페이스를 통해 창 테두리와 같은 미세한 세부 사항을 개인화하고 변경할 수 있습니다. 이 가이드에서는 Windows 운영 체제에서 자신의 스타일을 반영하는 환경을 만드는 데 도움이 되는 단계별 지침을 설명합니다. 창 테두리 설정을 변경하는 방법은 무엇입니까? +를 눌러 설정 앱을 엽니다. Windows개인 설정으로 이동하여 색상 설정을 클릭합니다. 색상 변경 창 테두리 설정 창 11" Width="643" Height="500" > 제목 표시줄 및 창 테두리에 강조 색상 표시 옵션을 찾아 옆에 있는 스위치를 토글합니다. 시작 메뉴 및 작업 표시줄에 강조 색상을 표시하려면 시작 메뉴와 작업 표시줄에 테마 색상을 표시하려면 시작 메뉴와 작업 표시줄에 테마 표시를 켭니다.

기본적으로 Windows 11의 제목 표시줄 색상은 선택한 어두운/밝은 테마에 따라 다릅니다. 그러나 원하는 색상으로 변경할 수 있습니다. 이 가이드에서는 이를 변경하고 데스크톱 환경을 개인화하여 시각적으로 매력적으로 만드는 세 가지 방법에 대한 단계별 지침을 논의합니다. 활성 창과 비활성 창의 제목 표시줄 색상을 변경할 수 있습니까? 예, 설정 앱을 사용하여 활성 창의 제목 표시줄 색상을 변경하거나 레지스트리 편집기를 사용하여 비활성 창의 제목 표시줄 색상을 변경할 수 있습니다. 이러한 단계를 알아보려면 다음 섹션으로 이동하세요. Windows 11에서 제목 표시줄 색상을 변경하는 방법은 무엇입니까? 1. 설정 앱을 사용하여 +를 눌러 설정 창을 엽니다. Windows"개인 설정"으로 이동한 다음

Windows Installer 페이지에 "OOBELANGUAGE" 문과 함께 "문제가 발생했습니다."가 표시됩니까? 이러한 오류로 인해 Windows 설치가 중단되는 경우가 있습니다. OOBE는 즉시 사용 가능한 경험을 의미합니다. 오류 메시지에서 알 수 있듯이 이는 OOBE 언어 선택과 관련된 문제입니다. 걱정할 필요가 없습니다. OOBE 화면 자체에서 레지스트리를 편집하면 이 문제를 해결할 수 있습니다. 빠른 수정 – 1. OOBE 앱 하단에 있는 “다시 시도” 버튼을 클릭하세요. 그러면 더 이상의 문제 없이 프로세스가 계속됩니다. 2. 전원 버튼을 사용하여 시스템을 강제 종료합니다. 시스템이 다시 시작된 후 OOBE가 계속되어야 합니다. 3. 인터넷에서 시스템 연결을 끊습니다. 오프라인 모드에서 OOBE의 모든 측면을 완료하세요.

작업 표시줄 축소판은 재미있을 수도 있지만 주의를 산만하게 하거나 짜증나게 할 수도 있습니다. 이 영역 위로 얼마나 자주 마우스를 가져가는지 고려하면 실수로 중요한 창을 몇 번 닫았을 수도 있습니다. 또 다른 단점은 더 많은 시스템 리소스를 사용한다는 것입니다. 따라서 리소스 효율성을 높일 수 있는 방법을 찾고 있다면 비활성화하는 방법을 알려드리겠습니다. 그러나 하드웨어 사양이 이를 처리할 수 있고 미리 보기가 마음에 들면 활성화할 수 있습니다. Windows 11에서 작업 표시줄 축소판 미리 보기를 활성화하는 방법은 무엇입니까? 1. 설정 앱을 사용하여 키를 탭하고 설정을 클릭합니다. Windows에서는 시스템을 클릭하고 정보를 선택합니다. 고급 시스템 설정을 클릭합니다. 고급 탭으로 이동하여 성능 아래에서 설정을 선택합니다. "시각 효과"를 선택하세요.

Windows 11의 디스플레이 크기 조정과 관련하여 우리 모두는 서로 다른 선호도를 가지고 있습니다. 큰 아이콘을 좋아하는 사람도 있고, 작은 아이콘을 좋아하는 사람도 있습니다. 그러나 올바른 크기 조정이 중요하다는 점에는 모두가 동의합니다. 잘못된 글꼴 크기 조정이나 이미지의 과도한 크기 조정은 작업 시 생산성을 저하시킬 수 있으므로 시스템 기능을 최대한 활용하려면 이를 사용자 정의하는 방법을 알아야 합니다. Custom Zoom의 장점: 화면의 텍스트를 읽기 어려운 사람들에게 유용한 기능입니다. 한 번에 화면에서 더 많은 것을 볼 수 있도록 도와줍니다. 특정 모니터 및 응용 프로그램에만 적용되는 사용자 정의 확장 프로필을 생성할 수 있습니다. 저사양 하드웨어의 성능을 향상시키는 데 도움이 될 수 있습니다. 이를 통해 화면의 내용을 더 효과적으로 제어할 수 있습니다. 윈도우 11을 사용하는 방법

화면 밝기는 최신 컴퓨팅 장치를 사용할 때 필수적인 부분이며, 특히 화면을 장시간 볼 때 더욱 그렇습니다. 눈의 피로를 줄이고, 가독성을 높이며, 콘텐츠를 쉽고 효율적으로 보는 데 도움이 됩니다. 그러나 설정에 따라 밝기 관리가 어려울 수 있으며, 특히 새로운 UI 변경이 적용된 Windows 11에서는 더욱 그렇습니다. 밝기를 조정하는 데 문제가 있는 경우 Windows 11에서 밝기를 관리하는 모든 방법은 다음과 같습니다. Windows 11에서 밝기를 변경하는 방법 [10가지 설명] 단일 모니터 사용자는 다음 방법을 사용하여 Windows 11에서 밝기를 조정할 수 있습니다. 여기에는 단일 모니터를 사용하는 데스크탑 시스템과 노트북이 포함됩니다. 시작하자. 방법 1: 알림 센터 사용 알림 센터에 액세스할 수 있습니다.

iOS 17에서 Apple은 모바일 운영 체제에 몇 가지 새로운 개인 정보 보호 및 보안 기능을 도입했습니다. 그 중 하나는 Safari의 개인 탐색 탭에 대해 2단계 인증을 요구하는 기능입니다. 작동 방식과 끄는 방법은 다음과 같습니다. iOS 17 또는 iPadOS 17을 실행하는 iPhone 또는 iPad에서 Safari에 개인 정보 보호 브라우징 탭이 열려 있는 경우 이제 Apple 브라우저에 Face ID/Touch ID 인증이나 암호가 필요하며, 다시 액세스하려면 세션이나 앱을 종료해야 합니다. 즉, 잠금이 해제된 iPhone이나 iPad를 다른 사람이 손에 넣는 경우에도 비밀번호를 모르면 개인정보를 볼 수 없습니다.
