user534498
user534498

Reputation: 3984

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.

Upvotes: 0

Views: 74

Answers (2)

Wolph
Wolph

Reputation: 80061

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.

Upvotes: 1

Abhik Chakraborty
Abhik Chakraborty

Reputation: 44864

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

Upvotes: 1

Related Questions