我們都知道如果不配置 enableSchemaCache => true
,那麼Yii每次操作數據庫都會有一堆類似這樣的SQL。
SELECT
`kcu`.`CONSTRAINT_NAME` AS `constraint_name`,
`kcu`.`COLUMN_NAME` AS `column_name`,
`kcu`.`REFERENCED_TABLE_NAME` AS `referenced_table_name`,
`kcu`.`REFERENCED_COLUMN_NAME` AS `referenced_column_name`
FROM `information_schema`.`REFERENTIAL_CONSTRAINTS` AS `rc`
JOIN `information_schema`.`KEY_COLUMN_USAGE` AS `kcu` ON
(
`kcu`.`CONSTRAINT_CATALOG` = `rc`.`CONSTRAINT_CATALOG` OR
(`kcu`.`CONSTRAINT_CATALOG` IS NULL AND `rc`.`CONSTRAINT_CATALOG` IS NULL)
) AND
`kcu`.`CONSTRAINT_SCHEMA` = `rc`.`CONSTRAINT_SCHEMA` AND
`kcu`.`CONSTRAINT_NAME` = `rc`.`CONSTRAINT_NAME`
WHERE `rc`.`CONSTRAINT_SCHEMA` = database() AND `kcu`.`TABLE_SCHEMA` = database()
AND `rc`.`TABLE_NAME` = 'users_data' AND `kcu`.`TA
每次更新數據都會有這麼長一條SQL會被執行,而線上運行的項目,表結構也不會經常改變,所以這種每次這種查詢有點太浪費性能了,徒增IO,所以一般線上穩定運行的項目,我們會開啓 schemaCache。
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=127.0.0.1;dbname=testdb',
'username' => 'root',
'password' => '1234567',
'charset' => 'utf8mb4',
'enableSchemaCache' => true,
'schemaCacheDuration' => 3600, // Duration of schema cache.
'schemaCache' => 'redis', // Name of the cache component used to store schema information
]
和 schemaCache有關的主要是三個參數
enableSchemaCache 是否開啓schema緩存
schemaCacheDuration schema緩存的時間,單位s
schemaCache 存儲schema信息的緩存組件的名稱
主要是 schemaCache這個配置,如果你不配置,Yii會找 cache組件,默認情況下是cache組件是這樣的。
可以看到默認是通過文件緩存的方式緩存schema信息,但是我手懂配置了 'schemaCache' => 'redis'
,所以Yii框架去找我的 redis 組件是去緩存schema信息,我的redis組件是什麼樣的呢。
'components' => [
'redis' => [
'class' => 'yii\redis\Connection',
'hostname' => '127.0.0.1',
'port' => 6379,
'password' => '1234567',
'database' => 0,
],
]
可以看到我的redis組件只是一個redis的連接,class是 yii\redis\Connection,然後我以爲一切都萬事大吉了,直到今天我查看runtime的log,我發現每次更新數據的時候還是會查詢information_schema表,每次還是會有開頭的長SQL被執行,爲什麼我的schemaCache沒有生效呢???
然後我看了一下如果我不配置'schemaCache' => 'redis',他會找cache組件,而cache組件是一個yii\caching\FileCache,它實現了 yii\caching\CacheInterface 接口,而 yii\caching\CacheInterface接口定義了一系列增刪改查的方法。