【问题标题】:Database query optimization (MySql)数据库查询优化(MySql)
【发布时间】:2015-06-30 07:21:45
【问题描述】:

我有三张桌子。

  1. 雷达数据表(以id为主),也有provision_file_id和provision_speed_id两列。

  2. Violation_speed 表(以 id 为主)

  3. violation_file 表(以 id 为主)

我想选择所有雷达数据,限制为 1000,从某个开始间隔到结束间隔,加入违规速度表。每个雷达数据都必须有一个violation_speed_id。

然后我想加入违规文件表,但不是每个雷达记录都对应于违规文件ID,有些记录的违规文件ID为0,表示没有相应的文件。

我现在的sql是这样的,

$results = DB::table('radar_data')
    ->join('violation_speed', 'radar_data.violation_speed_id', '=', 'violation_speed.id')
    ->leftjoin('violation_video_file', 'radar_data.violation_video_file_id', '=', 'violation_video_file.id')
    ->select('radar_data.id as radar_id',
      'radar_data.violation_video_file_id',
      'radar_data.violation_speed_id',
      'radar_data.speed',
      'radar_data.unit',
      'radar_data.violate',
      'radar_data.created_at',
      'violation_speed.violation_speed',
      'violation_speed.unit as violation_unit',
      'violation_video_file.video_saved',
      'violation_video_file.video_deleted',
      'violation_video_file.video_uploaded',
      'violation_video_file.path',
      'violation_video_file.video_name')
    ->where('radar_data.violate', '=', '1')
    ->orderBy('radar_data.id', 'desc')
    ->offset($from_id)
    ->take($max_length)
    ->get();

它是 PHP Laravel。但我认为翻译成mysql语句是直接的。

我的问题是,选择这样的数据是一种好方法吗?我试过了,但是如果雷达数据增长到一个很大的值,它似乎有点慢。

谢谢。

【问题讨论】:

    标签: php mysql database laravel join


    【解决方案1】:

    假设您设置了正确的索引,这在很大程度上是要走的路,唯一对我来说不是 100% 清楚的是 offset() 方法的作用,但如果它只是添加一个 WHERE 子句,那么这应该为您提供您将获得的最佳性能。如果没有,请将其替换为where('radar_data.id', '>', $from_id)

    这里最重要的索引是外键和主键上的索引。并确保不要忘记violate 索引。

    【讨论】:

    • offset 是 mysql 中限制的一部分——我认为框架不会改变这一点——如 limit 10 offset 20
    • @ArtisiticPhoenix:根据使用skip() 的文档,将在查询中为您提供OFFSETlaravel.com/docs/5.1/queries#ordering-grouping-limit-and-offset 另外,由于他正在传递$from_id,我认为这实际上是一个 where 查询/而是过滤。否则$from_id 将是错误的
    • 不太了解 Laravel,但我知道排序会影响你的表现:-p
    • 我也不知道,数据库性能我知道,但 Laravel... 从未使用过它:P
    • 我使用了学说(糟糕的体验),之后查询构建器对我来说很丑陋。大声笑
    【解决方案2】:

    查询速度通常取决于对所使用的joining clausewhere clause 使用正确的索引。

    在您的查询中有 2 个连接,如果连接键没有被索引,那么您可能需要应用以下内容

    alter table radar_data add index violation_speed_id_idx(violation_speed_id);
    
    alter table radar_data add index violation_video_file_id_idx(violation_video_file_id);
    
    alter table radar_data add index violate_idx(violate);
    

    id 是主键,因此它们已经被索引并且应该被覆盖

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-18
      • 1970-01-01
      • 1970-01-01
      • 2011-02-27
      • 1970-01-01
      相关资源
      最近更新 更多