Laravel 中有类似 Yii 2.0 中的 Schema 缓存吗?

Yii 2.0 性能优化的文档中看到 Schema 缓存的概念,内容如下:

开启 Schema 缓存

Schema 缓存是一个特殊的缓存功能, 每当你使用活动记录时应该要开启这个缓存功能。如你所知, 活动记录能智能检测数据库对象的集合(例如列名、列类型、约束)而不需要手动地描述它们。 活动记录是通过执行额外的SQL查询来获得该信息。 通过启用 Schema 缓存,检索到的数据库对象的集合将被保存在缓存中并在将来的请求中重用。

要开启 Schema 缓存,需要配置一个 cache 应用组件来储存 Schema 信息, 并在 配置 中设置 yii\db\Connection::$enableSchemaCache 为 true :

return [
    // ...
    'components' => [
        // ...
        'cache' => [
            'class' => 'yii\caching\FileCache',
        ],
        'db' => [
            'class' => 'yii\db\Connection',
            'dsn' => 'mysql:host=localhost;dbname=mydatabase',
            'username' => 'root',
            'password' => '',
            'enableSchemaCache' => true,

            // Duration of schema cache.
            'schemaCacheDuration' => 3600,

            // Name of the cache component used to store schema information
            'schemaCache' => 'cache',
        ],
    ],
];

我在公司用 Yii 2.0 开发的一个内部项目中尝试了一下,真的明显提升了速度,我想知道 Laravel 有没有提供这个 shema 缓存。

本帖已被设为精华帖!
本帖由 Summer 于 6年前 加精
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 10

Yii需要查询schema,是因为Yii根据表生成的Model是没有属性可以标记主键字段的

假设UserModel类对应的是user表,user表的主键是id,那么当你使用

$user = UserModel::findOne(1);

这种代码时,它需要查一下UserModel对应的user表的schema,才知道user表的主键是id,才能构造出select * from user where id = 1这条sql语句

假设你user表添加了字段password,但是并没有添加到UserModel
当你使用

$user->password = 123456;
$user->save();

Yii需要再次查询schema,确保user表里有'password'字段,才会构造出update user set password = '123456' where id = 1这条sql语句

这就是启用了schema缓存之后,能提升性能的原因

6年前 评论
Summer

@leoyang 邀请回答

6年前 评论

@Summer 受宠若惊!不过这方面我还真没听说过,数据库 scheme 我还没有研究过,不好意思

6年前 评论

@纸牌屋弗兰克 @Summer 我看了下 yii2 框架的这个 scheme 缓存, 由于 laravel 并没有关于 php 类型与数据库列类型之间的映射关系,因此也就并不存在缓存这种映射关系的 scheme 缓存。不过我比较好奇,为何 yii2 框架添加这个与数据库的映射关系

6年前 评论

@leoyang 我加了这个之后性能立马提升很有效果

6年前 评论

@leoyang 表结构变更的时候,不用修改 PHP 代码,Yii 会从数据获取新的表结构,比如 user 表新增一个字段 phone,那么任何使用 user 模型的地方都可以直接使用 $user->phone

6年前 评论

@l669306630 这个功能是在 select(*) 基础上的吧,不懂 yii2 框架,但是尽量少用 select(*)

6年前 评论

@纸牌屋弗兰克 这个是因为不加 scheme 缓存,每次 yii2 框架会发出额外的 sql 语句来查询表结构,但是 laravel 并没有查询表结构,我也不清楚 yii2 框架这么做的原因

6年前 评论

@leoyang 嗯嗯是的 :抱拳

6年前 评论

Yii需要查询schema,是因为Yii根据表生成的Model是没有属性可以标记主键字段的

假设UserModel类对应的是user表,user表的主键是id,那么当你使用

$user = UserModel::findOne(1);

这种代码时,它需要查一下UserModel对应的user表的schema,才知道user表的主键是id,才能构造出select * from user where id = 1这条sql语句

假设你user表添加了字段password,但是并没有添加到UserModel
当你使用

$user->password = 123456;
$user->save();

Yii需要再次查询schema,确保user表里有'password'字段,才会构造出update user set password = '123456' where id = 1这条sql语句

这就是启用了schema缓存之后,能提升性能的原因

6年前 评论

Yii文档对于schema缓存有点管杀不管埋的样子,并没有说怎么清除schema缓存

实际上你需要调用继承了yii\db\Schema的类,如yii\db\mysql\Schemarefresh()函数

或者在命令行下运行 php yii cache/flush-schema ,可以参考http://www.yiiframework.com/doc-2.0/yii-console-controllers-cachecontroller.html#actionFlushSchema()-detail

6年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!