简体   繁体   中英

Database query optimization (MySql)

I have three tables.

  1. Radar data table (with id as primary), also has two columns of violation_file_id, and violation_speed_id.

  2. Violation_speed table (with id as primary)

  3. violation_file table (with id as primary)

I want to select all radar data, limited by 1000, from some start interval to an end interval, joins with violation_speed table. Each radar data must have a violation_speed_id.

I want to then join with the violation_file table, but not each radar records corresponding to violation_file_id, some records just has violation_file_id of 0, means there's no curresponding file.

My current sql is like this,

$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();

It is PHP Laravel. But I think the translation to mysql statement is straight away.

My question is, is it a good way to select data like this? I tried but it seems a bit slow if the radar data grows to a large value.

Thanks.

The speed of the query often relies on the use of proper indexing on the joining clause and where clause used.

In your query there are 2 joins and if the joining keys are not indexed then you might need to apply the following

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);

The ids are primary key hence they are already indexed and should be covered

Assuming you have the proper indices set this is largely the way to go, the only thing that's not 100% clear to me is what the offset() method does, but if it simply adds a WHERE clause than this should give you pretty much the best performance you're going to get. If not, replace it with a where('radar_data.id', '>', $from_id)

The most important indices are the ones on the foreign keys and primary keys here. And make sure not to forget the violate index.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM