deleted_at 系统默认允许为 null 是否会有性能问题?
传说mysql里允许null的字段会忽略索引,那么也就不会去建索引。
那么问题来了,laravel里的deleted_at
字段默认nullable()
,查询的时候where xxx is null
来查询的,如果数据量大了,会否有性能问题呢?
现实场景:一般系统deleted_at is not null
的命中率不会高,估计低于5%
吧
高认可度评论:
是这样的,deleted_at 字段本身没必要加索引的,按照优化规则,他只存在两种可能,所以没有加索引的必要,
关于sql优化中的允许为空的这一块(各种优化原则,不建议允许字段为空),其实说的不够全面,确实允许会对优化有影响,但是说的是索引的时候的影响,对于不考虑索引的字段,设置为允许为空是没什么影响的,
举个例子:对于 用户的生日 有的人没设置,有的人设置了,假如你的业务类型几乎都是以生日来排序的,这时候可能你需要加一个索引来提高查询效率,但是呢,你又想标记是否设置,所以你用了 null 来代表没设置否则有日期则为设置,那么这样即允许为空,又有索引,是会影响一些效率的,但是官方也说了,这个不作为主要优化手段,仅作为一个额外考虑的优化手段;
回过头来可以发现,其实delete_at 允许为空是不会影响什么的,本身也不会去为这个字段加索引
deleted_at字段一般是自己设置的吧,created_at和updated_at才是laravel自动生成的吧
嗯,听起来会有问题
@程事不足 deleted_at是软删除的预设字段呀
NUll并不影响索引使用的,请阅读http://dev.mysql.com/doc/refman/5.5/en/problems-with-null.html
The column deleted_at is not a good index candidate. I'll try to explain better compared to the comment: indexes are useful only when their cardinality is relatively high. Cardinality is a number that describes index uniqueness in the data-set. That means it's total number of records divided by total unique records.
For example, the cardinality of primary key is 1. Every record contains unique value for primary key. 1 is also, the highest number. You can consider it as a "100%".
But, a column such as deleted_at doesn't have such a value. What Laravel does with deleted_at is check whether it is or isn't null. That means it has two possible values. Columns that contain two values have extremely low cardinality which decreases as number of records goes up.
You can index such a column, but it won't be of any help. What will happen is that it could slow things down and take up space.
TL;DR: no, you don't have to index that column, index will have no beneficial impact on performance.
引自:http://stackoverflow.com/questions/2652506...
Laravel SoftDeletes With Unix Timestamp
自己写 trait SoftDelete
@12 null column 是不影响索引的使用,但是在null column 字段增加索引后的效果是什么样的,索引会发挥作用吗?
碰到了, 表示问题慢...
这帖一年了,所以。。。结论到底是啥:joy:
@nff93 按照大家给的资料, mysql 5.5+ 没影响
是这样的,deleted_at 字段本身没必要加索引的,按照优化规则,他只存在两种可能,所以没有加索引的必要,
关于sql优化中的允许为空的这一块(各种优化原则,不建议允许字段为空),其实说的不够全面,确实允许会对优化有影响,但是说的是索引的时候的影响,对于不考虑索引的字段,设置为允许为空是没什么影响的,
举个例子:对于 用户的生日 有的人没设置,有的人设置了,假如你的业务类型几乎都是以生日来排序的,这时候可能你需要加一个索引来提高查询效率,但是呢,你又想标记是否设置,所以你用了 null 来代表没设置否则有日期则为设置,那么这样即允许为空,又有索引,是会影响一些效率的,但是官方也说了,这个不作为主要优化手段,仅作为一个额外考虑的优化手段;
回过头来可以发现,其实delete_at 允许为空是不会影响什么的,本身也不会去为这个字段加索引
@dingdejing『只是针对索引字段』 很精辟呀
@Summer @dingdejing
在这里延伸问一个问题:
deleted_at
默认值为null
,这一点在给表创建唯一约束的时候有冲突,MySQL
和PgSQL
(其他数据库暂不了解)中唯一约束允许多个null
值存在。使用软删除可能碰到的问题:如果表中有唯一约束的字段,比如
User
表的username
,一行记录被软删除后,username
已经被占用了,新的数据不能使用该username
。而如果将
deleted_at
加入唯一约束,由于deleted_at
默认值是null
,MySQL
和PgSQL
下唯一值是不校验NULL
的,即唯一值列出现多个NULL
值都不会报错。这就有点尴尬了,如果一张表想加入唯一约束,就不能使用软删除功能,要不然就重写软删除逻辑,给
deleted_at
设置一个默认值,但这应该有违Laravel设计的本意,Laravel内是不是提供其他解决方式?我不是很熟悉,所以在此请教 :pray:@Herjew 你这种情况就是在校验username的时候也要包含deleted_at not null
@5J 不是校验逻辑问题,是数据库的唯一约束功能 与 deleted_at 设定之间的冲突,我转而提了个问题 在这里。
@Herjew 如果不是业务上必要用唯一索引来做数据限制,性能上普通索引效率更好。