I agree with the Unreason branch , however . But there is something you need to know about this case.
This is called skew and skew. This is an ideal use for a partial index, in which you would exclude 95% of paid bills and indicate only more interesting and selective statistics. But you don’t have it. You can horizontally split all rows into separate tables / partitions, but then you need to consider row migration (moving from one status to another) and it’s expensive. The DBMS must perform an update, delete, and insert to change the status. If you are a system with a large volume that will hurt.
Forget what you said about whether to index based on selectivity, because adding an index to a fast-changing column is also a bad idea. Your index will have hot blocks, where all steps 1 are deleted, and the other, where the whole step 2 is inserted, and oh btw, some steps 2 are simultaneously deleted to step 3. This will not scale well.
I would recommend vertically dividing your status into separate tables.
The invoice table will show PK and all columns except status.
You can process your status in two ways. This table will have a PK value of FK for the table of accounts, status and time stamp when you entered this status. Best of all is a horizontally split status table. You will have a section for each state. Thus, upon detection of all or one “Hosted” status, cropping will be divided and only the section that he needs to read will be read - this is a very small number of blocks. Since the line is so narrow, you can get 400 account statuses on one block. Finding the status of any invoice is easy as there is a global index on the PC.
If your RDBMS does not support split with row migration, you need to manage these sections in the form of tables and delete them from one and paste them into another. You will encapsulate these movements in a transaction in a procedure to keep the data clean. Each invoice is in one and only one status table. The more difficult part is the request by invoice ID, you will need to check each table to see where it is.
You have another choice. You can either write paid statuses or not. If it is a partitioned table, you can simply delete the invoice from the account status table when it moves to the paid one. (Of course, you will write a paid report in the history table mentioned in the bonus material). Then you will make an external join in the status table, and null - the average payment. If you almost never ask for paid status, there really is no reason for a quick request.
Bonus Material
In any case, you want to track these movements in the report table. Each time you update a status, you want to write it to the history table. In the end, you will want to analyze what I call transit time. What is the average time from filling to paid, by months? Does this increase as a result of a poor economy? that the transit time from place to fill is monthly. Does the summer months take longer due to lack of body on vacation? you understand. By updating this column, you are losing these answers, so you need to incorporate this history log into your procedures.