Tutorial

ลดขนาด Home Assistant Database 100 เท่า! จาก 200GB เหลือไม่ถึง 1GB ด้วย Config ง่าย ๆ

By Arnon Puitrakul - 03 มกราคม 2026

ลดขนาด Home Assistant Database 100 เท่า! จาก 200GB เหลือไม่ถึง 1GB ด้วย Config ง่าย ๆ

ก่อนหน้านี้ เราใช้งาน Home Assistant ไปเรื่อย ๆ แล้วเจอปัญหาว่า ข้อมูลกราฟต่าง ๆ โหลดช้าลงเรื่อย ๆ ก็ไม่ได้คิดอะไรมาก จนมันใช้ไม่ได้เลย วันนี้เราจะมาเล่าให้อ่านกันว่าเราแก้ปัญหายังไงและทำยังไงถึงย่อขนาดให้เหลือ 600 MB กว่า ๆ และไม่โตไปเรื่อย ๆ ได้

The Discovery

ก่อนหน้านี้ เราขยับจาก SQLite ที่เป็น Default ของ Home Assistant มาเป็น MySQL เพราะความแข็งแกร่งที่มากกว่า SQLite ที่เป็น File-Based Database เยอะมาก ๆ รวมไปถึงเรื่องของการ Backup และการจัดการต่าง ๆ ที่ MySQL ทำได้ง่าย และยืดหยุ่นกว่ากันมาก ๆ

แรก ๆ เราใช้งานไป มันใช้งานได้ปกติ ไม่มีอะไรเลย เผลอ ๆ เร็วกว่า SQLite หลายขุมมาก ๆ แต่เมื่อใช้งานไปเรื่อย ๆ เริ่มเจอปัญหาว่า หน้ากราฟพลังงานจาก Solar Cell ที่เคยโหลดเร็ว ๆ เปิดเข้ามาปุ๊บขึ้นปั๊บเลย กลายเป็นโหลดนานมากขึ้นไปเรื่อย ๆ จนหลัง ๆ คือนาน จนเราไม่ดูไปแล้ว และท้ายสุด Home Assistant ฟ้องว่า Recorder ไม่สามารถเริ่มต้นการทำงานได้ อันนี้แหละ เป็นจุดที่เราเริ่มเข้ามาตรวจสอบแล้วว่ามันเกิดอะไรขึ้น

ตอนแรกเราเข้าใจว่า Database มันล่ม หรือ Container มันไม่ยอม Start ก็เลยไปเช็คกับ Container Service มันยังทำงานได้ตามปกติ และ DataGrip ยัง Connect เข้าไป Query ข้อมูลได้ตามปกติ แค่ว่า มันช้าหน่อยเท่านั้นเอง จนเริ่มลองไปทำ Execution Plan ปรากฏว่า ชิบหาย !! ทำไมจำนวน Record มันใหญ่ขนาดนั้น

เลยไปเช็คขนาดของ Database ใน File ดู ปรากฏว่า กดไป 230 GB กว่า ๆ ซึ่งมันใหญ่มาก ๆ ใหญ่เกินว่าที่เราคิดไปไกลมาก ๆ ไม่แปลกเลยที่มันจะพังยับได้ขนาดนี้ เพราะ Query ที มันต้อง Search ไล่ Row จำนวนเยอะขนาดนั้น ไม่แปลกที่มันจะสิ้นชีพ เราพยายามทำหลายอย่างมาก เพื่อที่จะไม่ต้องทิ้ง Data เก่า แต่สุดท้าย เราก็ไม่รู้จะทำยังไงเหมือนกันสุดท้าย เลยลบ Storage ของ Database Container ออกไป แล้ว Reset Container เริ่มใหม่ สร้าง Database ใหม่ แล้วค่อย Start Home Assistant ตัว Recorder ก็กลับมาทำงานได้อีกครั้ง ทำให้คิดว่าเป็นที่ขนาดของ Database ที่น่าจะทำให้เกิดปัญหา

Solutions

# Example filter to include specified domains and exclude specified entities
recorder:
  include:
    domains:
      - alarm_control_panel
      - light
    entity_globs:
      - binary_sensor.*_occupancy
  exclude:
    entities:
      - light.kitchen_light

เราเข้าไปดู Documentation ของ Recorder ปรากฏว่ามันมี Config หลายอย่างให้เราเลือกเซ็ตได้หลายอย่างมาก ๆ สามารถเข้าไปดูในเว็บของเขาได้เลย แต่สิ่งที่เราอยากให้ Focus คือ การจำกัด Entity ที่จะบันทึกเข้าไปใน Database และ Data Retention Period เพราะยิ่งจำนวนเยอะ และนานมากเท่าไหร่ ขนาดของ Database ก็จะใหญ่มากขึ้นเท่านั้น

ในค่า Default ของ Recorder หากเราไม่ได้กำหนดการกรอง Entity ที่จะบันทึกอะไรไว้เลย มันจะเลือกบันทึกทุก Entity เข้าไปหมด หากระบบเราไม่ได้ใหญ่มาก ไม่ได้มี Integration อะไรมากมาย ปัญหาจะไม่เกิด แต่ระบบเรามี Integration เสียบเข้าไปเยอะมาก มีหลายพัน Entity และหลาย ๆ ตัวมีการ Update ถี่มาก ๆ กินพื้นที่แบบโคตร ๆ ดังนั้น เราจะต้องมาจำกัด Entity ที่จะบันทึกเข้าไป โดยการใส่ Include และ Exclude ใน Config

include:
    entity_globs:
      - sensor.weather_station_*
      - sensor.2102313ttensn*_output_power
      - sensor.2102313ttensn*_temperature
      - sensor.2102313ttensn*_output_voltage
    entities:
      - switch.sonoff_rack_fan
      - sensor.master_bedroom_temperature
      - sensor.master_bedroom_humidity
      - sensor.master_bedroom_pm10
      - sensor.master_bedroom_pm2_5
      - sensor.living_room_air_purifier_temperature
      - sensor.living_room_air_purifier_humidity
      - sensor.living_room_air_purifier_pm2_5
      - sensor.gaming_room_air_purifier_temperature
      - sensor.gaming_room_air_purifier_humidity
      - sensor.gaming_room_air_purifier_pm2_5
      - sensor.pv_inverter_generate_power
      - sensor.pv_daily_generate_total_energy
      - sensor.pv_1_active_power
      - sensor.pv_2_active_power
      - sensor.pv_1_string_1_power
      - sensor.pv_1_string_2_power
      - sensor.pv_2_string_1_power
      - sensor.pv_inverter_generate_power
      - sensor.pv_power_metre_consumption_power
      - sensor.pv_self_consumption_power
      - sensor.pv_1_day_active_power_peak
      - sensor.pv_2_day_active_power_peak
      - sensor.pv_1_string_1_voltage
      - sensor.pv_1_string_2_voltage
      - sensor.pv_2_string_1_voltage
      - sensor.pv_1_energy_daily_yield
      - sensor.pv_2_energy_daily_yield

โดยเราจะเลือกใส่ Entity ที่ต้องการโชว์ข้อมูลย้อนหลัง นี่คือตัวอย่างของที่เราใช้งาน หลัก ๆ คือ จะเป็นข้อมูลจากระบบ Solar Cell, Climate ของห้องต่าง ๆ, Weather Station หน้าบ้าน และ พัดลมของตู้ Rack เท่านั้นเอง เพราะทั้งหมดนี้เป็นข้อมูลที่เรามีส่วนที่โชว์ข้อมูลย้อนหลังใน Frontend ส่วนที่เหลือ เราไม่จำเป็นต้องให้มันเก็บเลย บางส่วน เราไม่ได้ใช้ดู หรือ บางส่วนเราไม่ได้ต้องการดูย้อนหลัง แค่อยากได้ข้อมูลปัจจุบันเท่านั้นเอง

ถ้าเราเข้าไปดูใน Database ของ Home Assistant เราจะเห็นว่า นอกจากที่มันจะเก็บ State เรื่อย ๆ แล้วมันยังบันทึก Attributes ตามไปด้วย โดย State จะเก็บลงไปใน Table ชื่อว่า states และ Attribute มันจะมี Foreign Key ต่อไปที่ Table ชื่อว่า state_attributes ซึ่งบอกเลยว่า กินพื้นที่มหาศาล และ หลาย ๆ ครั้ง Attribute จะไม่ได้เปลี่ยนแปลงอะไรมากมาย ทำให้เราจะเจอกับปรากฏการณ์ข้อมูลซ้ำ ๆ กันเต็ม Database กินที่เราเต็มไปหมด

template:
  - sensor:
      - name: "Mikrotik Eth1 Tx Extracted"
        unit_of_measurement: "kb/s"
        state: "{{ states('sensor.mikrotik_eth1_tx')}}"

วิธีการแก้ไขคือ ให้เรา Extract เฉพาะ State ออกมาเป็น Entity ใหม่ที่ไม่มี Attribute เลี่ยงการเก็บ Entity ที่มี Attributes ซ้ำกันเยอะ ๆ จากนั้น เราค่อยเอา Template Sensor ตัวใหม่ Include เข้าไปบันทึกเก็บใน Database อีกที

# Example filter to include specified domains and exclude specified entities
recorder:
  auto_purge : true
  auto_repack: true
  purge_keep_days: 2
  commit_interval: 30

จากนั้น เราจะมาดูที่จำนวนวันที่เก็บ หรือ Data Retention Period กันบ้าง ตาม Common Sense ทั่ว ๆ ไปคือ ยิ่งเก็บนานเท่าไหร่ยิ่งกินพื้นที่เยอะมากขึ้นเท่านั้น เราจะต้องมาคิดว่า แล้วเราจะเก็บกี่วันดี ส่วนใหญ่เราเอง ก็จะดูย้อนหลังแค่ 1-2 วันเท่านั้น เราก็เลยจะไปตั้งค่าเพิ่ม ตรง purge_keep_days ให้เราใส่เข้าไปเลย เราจะให้มันเก็บข้อมูลไว้กี่วัน จากตัวอย่างด้านบน เราจะตั้งไว้แค่ 2 วันเท่านั้น ส่วนตัวเลือก 2 ตัวข้างบนที่เหลือ เป็นการตั้งค่าให้มันลบข้อมูลเองอัตโนมัติ หากเราตั้งค่าเป็น True ไว้ ทุกคืนเวลา 4:12 am มันจะเข้าไปลบข้อมูลที่นานเกินที่เรากำหนดไว้ อีกอย่างที่อยากให้รู้ไว้คือ ค่า Default มันจะถูกตั้งไว้ 10 วัน ดังนั้น หากเราตั้งค่ามากกว่านั้น ข้อมูลเราก็อาจจะใหญ่ขึ้นแทนนะ

อีกค่าคือ Commit Interval มันคือการบอกว่า จะให้ Home Assistant เขียนข้อมูลลงไปทุกกี่วินาที หากเซ็ตเป็น 0 ตัว Home Assistant ก็จะเริ่มบันทึกทันทีที่มีการเปลี่ยนแปลง หากทำแบบนั้น บอกเลยว่า SSD และ SD Card สู่ขิตในเวลาอันสั้นแน่ ๆ ดังนั้น เราควรจะต้องเซ็ตให้พอดี ส่วนตัวเราจะไม่ได้เซ็ตให้มันเร็วมาก เราไม่ได้ต้องการความ Realtime ขนาดนั้น เราจะเซ็ตไว้ประมาณ 30 วินาที ก็ถือว่าโคตรเร็วมาก ๆ แล้ว สามารถเอาขึ้นไปได้อีกเยอะมาก

alias: Purge PV Optimiser States
description: Purge PV Optimiser Measurement from DB
triggers:
  - trigger: time
    at: "00:10:00"
    weekday:
      - mon
      - tue
      - wed
      - thu
      - fri
      - sat
      - sun
conditions: []
actions:
  - action: recorder.purge_entities
    metadata: {}
    data:
      keep_days: 1
      entity_globs:
        - sensor.2102313ttensn*_output_power
        - sensor.2102313ttensn*_temperature
        - sensor.2102313ttensn*_output_voltage
mode: single

เพื่อความ Optimise มันเข้าไปอีก เราสามารถตั้งค่าให้มัน Purge หรือล้างข้อมูลของ Entity ที่เราไม่ต้องการเก็บนานเท่ากับตัวอื่น ๆ ได้ด้วย เช่นบ้านเราจะมีข้อมูลจาก Solar Optimiser ที่เราดูย้อนหลังนานสุด ก็แค่วันเดียว เราก็จะเขียน Automation ที่เรียก Service recorder.purge_entities ที่ทำให้เราสามารถเลือก Entity ที่เราต้องการลบออก พร้อมกับตั้งจำนวนที่เก็บไว้ได้ เราก็จะสั่งให้รันทุกเที่ยงคืน 10 นาที เท่านี้ข้อมูลที่เราไม่ต้องการให้เก็บนานเท่ากับข้อมูลอื่น ๆ ก็จะถูกล้างออกไปทุกคืนแล้ว

Long-Term Data Storage

อ่านถึงตอนนี้ ก็น่าจะสงสัยต่อว่า แล้วข้อมูลที่เราต้องการเก็บระยะยาว ๆ อย่าง ข้อมูลจาก Solar Cell และการใช้ไฟที่เราอยากจะเก็บไว้เป็นปี ๆ เพื่อเอามาวิเคราะห์การทำงานของ Solar Cell และการใช้ไฟฟ้าของเราละ เราจะทำอย่างไร

วิธีการคือ เราจะเอา Time Series Database มาช่วยเก็บ โดยตัวที่ Integrate เข้าไปใน Home Assistant ได้ง่ายมาก ๆ คือ InfluxDB เราสามารถเขียน Config โดยอ้างอิงจาก Documentation ของ Home Assistant ได้เลย

sensor:
  - platform: influxdb
    queries:
      - name: mean value of foo
        where: '"name" = ''foo'''
        measurement: '"°C"'

สนุกกว่านั้น เราสามารถเอาข้อมูลที่เก็บใน InfluxDB มา Query กลับมาเป็น State ได้ด้วย ดังนั้น ข้อมูลชุดไหนที่เราเก็บไว้ใน InfluxDB แล้ว เราไม่จำเป็นต้องเก็บลง MySQL ผ่าน Recorder แล้ว เราก็แค่เขียน Sensor อีกตัวมาเพื่อดึงข้อมูลขึ้นมา แล้วเอามาแสดงผลใน Frontend ได้เลย ก็จะทำให้เราประหยัดพื้นที่ในการเก็บข้อมูลเพิ่มได้อีก

อีกข้อดีของการดึงข้อมูลจาก Influx คือ เราสามารถเลือก Query ข้อมูลได้อิสระมากกว่า เช่น เราอยากได้ ค่าเฉลี่ย เราสามารถ Query เป็นค่าเฉลี่ยออกมาได้เลย เทียบกับ การจะต้องมานั่งหาค่าเฉลี่ยบน Frontend ก็ดูจะเป็นเรื่องที่ไม่ดีเท่าไหร่ ก็จะทำให้ Performance ในการโหลดข้อมูลมาแสดงผลต่าง ๆ ดีกว่ากันเยอะมาก

สรุป

หลังจากมานั่งวิเคราะห์การใช้งาน และปรับการตั้งค่า Home Assistant ส่วนที่ได้เล่าไปแล้ว ทำให้ Database ที่เคยมีขนาดหลัก 230 GB กว่า ขนาดเหลือเพียงแค่ 600 MB กว่า ๆ เท่านั้น และเมื่อกดโหลดหน้าที่มี Graph เยอะ ๆ ก็โหลดเร็ว จนเรียกว่า แทบจะขึ้นทันที เทียบกับก่อนหน้านี้ที่โหลดไม่ขึ้นเลย ใครที่ใช้ Home Assistant แล้วมี Entity เยอะ ๆ ก็ลองมาปรับจูนการตั้งค่าของ Recorder ได้ น่าจะช่วยลดพื้นที่ที่ต้องใช้ลง และ ทำให้อายุของหน่วยความจำเราอยู่ได้นานด้วย