0

パーティション分割されたテーブルに大規模なデータベース (1 分間に 6000 行が挿入されます) があります。データベースが小さいときは問題なく動作していましたが、現在は大規模なデータベースがあります。私はこのソリューションを日付で結合された以前のソリューションSQLを使用していましたが、250MBのハードディスクを使用しており、テーブルが大きくなるにつれて大きくなり、10行でうまく機能する単純なクエリの反復に変更することにしましたが、 10 台以上の車で遅く (応答に 15 秒)、200MB 以上のハードディスクを使用します。

私の質問は、この問題を解決するために適切なクエリをより速く構築する方法です

追加情報

  1. ajaxによってdjangoアプリでクエリが呼び出されます
  2. 完全なアイテムリストの応答を伴う1回の呼び出しではなく、反復的なajax呼び出しを考えていました
  3. テーブルは日ごとに分割されています

私の実際のクエリは

CREATE OR REPLACE FUNCTION gps_get_last_positions (
    _plates varchar(8)
)
RETURNS TABLE (
    plate varchar,
    device_id integer,
    date_time_process timestamp with time zone, 
    latitude double precision, 
    longitude double precision, 
    course smallint, 
    speed smallint, 
    mileage integer,
    gps_signal smallint,
    gsm_signal smallint,
    alarm_status boolean,
    gsm_status boolean,
    vehicle_status boolean,
    alarm_over_speed boolean,
    other text,
    realtime  double precision
) AS $func$
DECLARE 
    arr varchar[];

BEGIN
    arr := regexp_split_to_array(_plates, E'\\s+');
    FOR i IN 1..array_length(arr, 1) LOOP
        RETURN QUERY SELECT 
        gpstracking_vehicles.registration,
        gpstracking_device_tracks.device_id, 
        gpstracking_device_tracks.date_time_process,
        gpstracking_device_tracks.latitude,
        gpstracking_device_tracks.longitude,
        gpstracking_device_tracks.course,
        gpstracking_device_tracks.speed,
        gpstracking_device_tracks.mileage,
        gpstracking_device_tracks.gps_signal,
        gpstracking_device_tracks.gsm_signal,
        gpstracking_device_tracks.alarm_status,
        gpstracking_device_tracks.gps_status,
        gpstracking_device_tracks.vehicle_status,
        gpstracking_device_tracks.alarm_over_speed,
        gpstracking_device_tracks.other,
        EXTRACT(EPOCH FROM current_timestamp - gpstracking_device_tracks.date_time_process)/60 AS realtime
        FROM (
        gpstracking_devices INNER JOIN (
        gpstracking_vehicles INNER JOIN gpstracking_vehicles_devices ON ( gpstracking_vehicles.id = gpstracking_vehicles_devices.vehicle_id AND gpstracking_vehicles_devices.is_joined = TRUE )
        ) ON ( gpstracking_devices.id = gpstracking_vehicles_devices.device_id AND gpstracking_vehicles_devices.is_joined = TRUE )
        ) INNER JOIN gpstracking_device_tracks ON ( gpstracking_devices.id = gpstracking_device_tracks.device_id )
        WHERE gpstracking_vehicles.registration = arr[i]::VARCHAR
        ORDER BY gpstracking_device_tracks.date_time_process DESC
        LIMIT 1;
    END LOOP;
    RETURN;
END;
$func$ 
LANGUAGE plpgsql VOLATILE SECURITY DEFINER;

構成パラメータ

application_name            phpPgAdmin_5.0.4                    client
constraint_exclusion        on                                  configuration file
DateStyle                   ISO, MDY                            session
default_text_search_config  pg_catalog.english                  configuration file
external_pid_file           /var/run/postgresql/9.1-main.pid    configuration file
lc_messages                 en_US.UTF-8                         configuration file
lc_monetary                 en_US.UTF-8                         configuration file
lc_numeric                  en_US.UTF-8                         configuration file
lc_time                     en_US.UTF-8                         configuration file
log_line_prefix             %t                                  configuration file
log_timezone                localtime                           environment variable
max_connections             100                                 configuration file
max_stack_depth             2MB                                 environment variable
port                        5432                                configuration file
shared_buffers              24MB                                configuration file
ssl                         on                                  configuration file
TimeZone                    localtime                           environment variable
unix_socket_directory       /var/run/postgresql                 configuration file

私の最初の遅いクエリは次のとおりです。

CREATE OR REPLACE VIEW view_vehicle_devices AS
SELECT 
gpstracking_vehicles_devices.id AS id,
gpstracking_devices.id AS device_id,
gpstracking_vehicles.id AS vehicle_id,
gpstracking_drivers.id AS driver_id,
gpstracking_device_protocols.name AS protocol,
gpstracking_vehicles.registration AS plate,
gpstracking_drivers.firstname as first_name,
gpstracking_drivers.lastname as last_name,
gpstracking_devices.imei,
gpstracking_devices.simcard, 
gpstracking_device_tracks.date_time_process,
gpstracking_device_tracks.latitude,
gpstracking_device_tracks.longitude,
gpstracking_device_tracks.course,
gpstracking_device_tracks.speed,
gpstracking_device_tracks.mileage,
gpstracking_device_tracks.gps_signal,
gpstracking_device_tracks.gsm_signal,
gpstracking_device_tracks.alarm_status,
gpstracking_device_tracks.gps_status,
gpstracking_device_tracks.vehicle_status,
gpstracking_device_tracks.alarm_over_speed,
gpstracking_device_tracks.other,
gpstracking_device_tracks.point,
EXTRACT(EPOCH FROM current_timestamp - gpstracking_device_tracks.date_time_process)/60 realtime,
gpstracking_devices.created,
gpstracking_devices.updated,
gpstracking_devices.is_connected

FROM (
gpstracking_vehicles LEFT JOIN (
gpstracking_drivers  LEFT JOIN gpstracking_vehicles_drivers ON gpstracking_drivers.id = gpstracking_vehicles_drivers.driver_id AND gpstracking_vehicles_drivers.is_joined = TRUE
) ON gpstracking_vehicles.id = gpstracking_vehicles_drivers.vehicle_id AND gpstracking_vehicles_drivers.is_joined = TRUE
) LEFT JOIN (((
gpstracking_device_protocols RIGHT JOIN gpstracking_devices ON gpstracking_device_protocols.id = gpstracking_devices.device_protocol_id
) LEFT JOIN (
SELECT DISTINCT ON (gpstracking_device_tracks.device_id) gpstracking_device_tracks.device_id, 
gpstracking_device_tracks.date_time_process,
gpstracking_device_tracks.latitude,
gpstracking_device_tracks.longitude,
gpstracking_device_tracks.course,
gpstracking_device_tracks.speed,
gpstracking_device_tracks.mileage,
gpstracking_device_tracks.gps_signal,
gpstracking_device_tracks.gsm_signal,
gpstracking_device_tracks.alarm_status,
gpstracking_device_tracks.gps_status,
gpstracking_device_tracks.vehicle_status,
gpstracking_device_tracks.alarm_over_speed,
gpstracking_device_tracks.other,
gpstracking_device_tracks.point
FROM gpstracking_device_tracks 
ORDER BY gpstracking_device_tracks.device_id, gpstracking_device_tracks.date_time_process DESC
) AS gpstracking_device_tracks ON gpstracking_devices.id = gpstracking_device_tracks.device_id  
) LEFT JOIN gpstracking_vehicles_devices ON ( gpstracking_devices.id = gpstracking_vehicles_devices.device_id AND gpstracking_vehicles_devices.is_joined = TRUE )
) ON ( gpstracking_vehicles.id = gpstracking_vehicles_devices.vehicle_id AND gpstracking_vehicles_devices.is_joined = TRUE )

投稿を開始するループ用に変更しましたが、ループは高速化されていますが、必要なほど高速ではありません

4

1 に答える 1