Write efficient and chainable scopes:
- Return an ActiveRecord::Relation.
- Filter data in the database.
- Sort in the database.
- Ordering out of scopes.
Reduce calls to the database:
- Using
.joins(),.includes()sometimes you will have to use.having(),.group()and in some cases, write some straight upSQL.
Use indexes:
- Add an index on every id column as well as any column that is used in a where clause.
Use query objects for complicated queries:
def relation
user_ids = GroupUser.select(:user_id).where(activated: true)
User.where(id: user_ids)
endSELECT users.*
FROM users
WHERE users.id
IN (
SELECT group_users.user_id
FROM group_users
WHERE group_users.activated = 't'
)Avoid queries outside of scopes and query qbjects:
- Query embedded in a controller (or view, task, etc) is harder to test in isolation and cannot be reused.
Use the right types:
- Use the
citextwhen need to comparisons be case-insensitive. - Avoid
varchar,char, and anything else usetexttype. - Use the
arraytype when need store tags, keywords in case when separate table and join table looks like overkill. - When need a globally unique ID use
UUIDtype. - In case when need a NoSQL DB or store JSON blob use one of the
jsonbtype.
Active Record:
- Use an
enumattribute where the values map to integers in the database, but can be queried by name. - Don't user
.notmethod, it's don't use indexes. - Don't initialize ActiveRecord Objects in case when it is useless.
Make your job parameters simple:
UserWorker.perform_async(user_id)- The arguments that you pass should be composed of simple JSON datatypes.
Write idempotent and transactional jobs:
- Your job can safely execute multiple times.
Concurrency and Queue:
- Sidekiq process at a queue with a defined number of threads, configure you connection pool correct.
- When you have multiple instance of sidekiq run each instance in uniq queue.
Common practices:
- Use single responsibility and interface segregation principle when you plan your jobs.
- Use
delayed extensionsit provide a very easy and simple way to make method calls asynchronous.
- Use elasticsearch to store and work with denormalized data.
- Use
jsonborarrayto store denormalized data in table to reduce count of db queries. - Use extenders to avoid store denormalized data in db but it help to reduce count of db queries in spesific situations.