Saya menggunakan Laravel 4.2 dan aplikasi saya digunakan untuk melacak inventaris di beberapa lokasi.
Basis data diatur dengan tabel inventory_items
, tabel inventory_locations
, dan tabel pivot di antara keduanya inventory_items_inventory_location
, yang berisi nilai kuantitas sambil merujuk pada item inventaris dan lokasi milik catatan tersebut.
Permintaan saya adalah menemukan item inventaris yang memiliki nilai kuantitas lokasi lebih dari atau sama dengan 0. Di Laravel saya menggunakan subquery dan orWhere seperti:
InventoryItem::whereHas('inventoryLocations', function($q) {
$q->where('reserved', '>=', 0)
->orWhere('available', '>=', 0) # slow
->orWhere('inbound', '>=', 0) # slow
->orWhere('total', '>=', 0); # slow
})->toSql();
Yang memberikan SQL berikut:
select * from `inventory_items`
where `inventory_items`.`deleted_at` is null
and (
select count(*) from `inventory_locations`
inner join `inventory_item_inventory_location`
on `inventory_locations`.`id` = `inventory_item_inventory_location`.`inventory_location_id`
where `inventory_item_inventory_location`.`inventory_item_id` = `inventory_items`.`id`
and `reserved` >= ?
or `available` >= ? # slow
or `inbound` >= ? # slow
or `total` >= ? # slow
) >= 1
Masalahnya adalah dengan pernyataan or
(ditandai dalam kode dengan #slow
) waktu kueri hingga 1 detik secara langsung dengan Sekuel Pro, lebih dari 5 detik melalui aplikasi Laravel saya (atau melalui artisan tinker). Tanpa pemeriksaan 'atau' ini (yaitu hanya memeriksa satu jenis kuantitas misalnya 'dipesan') kuerinya adalah ‹100 md di Sekuel Pro dan serupa di aplikasi/tinker.
Saya tidak yakin mengapa menambahkan tanda 'atau' tambahan ini menambah banyak waktu pada kueri. Adakah ide bagaimana membuat kueri yang lebih berkinerja?
reserved
,available
,inbound
,total
tabel? - person num8er   schedule 30.12.2016available
,inbound
, dantotal
Anda? - person Rwd   schedule 30.12.2016>=
ke>
karena saya tidak melihat logikawhereHas('inventoryLocations')
. Maksud saya, Anda perlu memeriksa keberadaaninventoryLocations
jika data lebih dari nol. karena>=
mungkin mengembalikan semua data. - person num8er   schedule 30.12.2016=, >, <
dll. - person Mr Office   schedule 30.12.2016