INDEX and Table Indexing
SNMP tables - repeating data like one row per network interface, one row per routing entry - use an INDEX clause to define how a specific row gets identified. Understanding indexing is what turns "table columns are confusing OIDs with extra numbers on the end" into something that actually makes sense.
The simple case: a single integer index
The classic example is ifTable, indexed by ifIndex:
ifEntry OBJECT-TYPE
...
INDEX { ifIndex }
::= { ifTable 1 }
This means: to identify a specific row, you append the value of ifIndex for that row to the end of any column's OID. If interface 1 has ifIndex value 1, then ifDescr for that interface is at 1.3.6.1.2.1.2.2.1.2.1 - the column's own OID, plus .1 for the row.
Multi-column (compound) indexes
Not every table is indexed by a single simple integer. Some are indexed by multiple columns together, and the resulting instance suffix is the concatenation of all of them, in order. A classic example is a table indexed by both an interface index and an IP address:
INDEX { ifIndex, ipAddr }
If ifIndex is 1 and the IP address is 192.168.1.10, the instance suffix becomes 1.192.168.1.10 - the IP address encoded as four separate decimal numbers, one per octet, appended after the interface index. This is exactly why some real-world OIDs have long tails of numbers that look like an IP address hiding in plain sight - because that's often literally what they are.
Implied vs. fixed-length string indexes
When a string is used as part of an index, its encoding in the OID depends on whether it's declared with the IMPLIED keyword. Without IMPLIED, a variable-length string index is prefixed with its own length (so the parser knows where it ends and the next index component begins); with IMPLIED (only valid on the last index component), the string appears with no length prefix, since being last means there's no ambiguity about where it ends.
Why this matters when reading a walk
Once you understand that the trailing numbers after a column's base OID are an encoded index - not random noise - a long, unfamiliar-looking OID stops being intimidating. 1.3.6.1.2.1.4.22.1.2.1.192.168.1.1 isn't an arbitrary number; it's very likely ipNetToMediaPhysAddress (a column) indexed by an interface number (1) and an IP address (192.168.1.1), once you know to look for that pattern.
Where this shows up in practice
Every table-related question - why is this OID so long, how do I know which row this is, why does walking this table produce OIDs with a weird tail - traces back to indexing. It's also directly relevant to RowStatus, since creating a new row means choosing values for every index column as part of that row's own identity, not something you can change afterward.